| 
									
										
										
										
											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": | 
					
						
							| 
									
										
										
										
											2008-05-16 20:06:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _get_build_version(): | 
					
						
							|  |  |  |         """Return the version of MSVC that was used to build Python.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         For Python 2.3 and up, the version number is included in | 
					
						
							|  |  |  |         sys.version.  For earlier versions, assume the compiler is MSVC 6. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # This function was copied from Lib/distutils/msvccompiler.py | 
					
						
							|  |  |  |         prefix = "MSC v." | 
					
						
							|  |  |  |         i = sys.version.find(prefix) | 
					
						
							|  |  |  |         if i == -1: | 
					
						
							|  |  |  |             return 6 | 
					
						
							|  |  |  |         i = i + len(prefix) | 
					
						
							|  |  |  |         s, rest = sys.version[i:].split(" ", 1) | 
					
						
							|  |  |  |         majorVersion = int(s[:-2]) - 6 | 
					
						
							|  |  |  |         minorVersion = int(s[2:3]) / 10.0 | 
					
						
							|  |  |  |         # I don't think paths are affected by minor version in version 6 | 
					
						
							|  |  |  |         if majorVersion == 6: | 
					
						
							|  |  |  |             minorVersion = 0 | 
					
						
							|  |  |  |         if majorVersion >= 6: | 
					
						
							|  |  |  |             return majorVersion + minorVersion | 
					
						
							|  |  |  |         # else we don't know what version of the compiler this is | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def find_msvcrt(): | 
					
						
							|  |  |  |         """Return the name of the VC runtime dll""" | 
					
						
							|  |  |  |         version = _get_build_version() | 
					
						
							|  |  |  |         if version is None: | 
					
						
							|  |  |  |             # better be safe than sorry | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         if version <= 6: | 
					
						
							|  |  |  |             clibname = 'msvcrt' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             clibname = 'msvcr%d' % (version * 10) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # If python was built with in debug mode | 
					
						
							|  |  |  |         import imp | 
					
						
							|  |  |  |         if imp.get_suffixes()[0][0] == '_d.pyd': | 
					
						
							|  |  |  |             clibname += 'd' | 
					
						
							|  |  |  |         return clibname+'.dll' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |     def find_library(name): | 
					
						
							| 
									
										
										
										
											2008-05-16 20:06:31 +00:00
										 |  |  |         if name in ('c', 'm'): | 
					
						
							|  |  |  |             return find_msvcrt() | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         # See MSDN for the REAL search order. | 
					
						
							|  |  |  |         for directory in os.environ['PATH'].split(os.pathsep): | 
					
						
							|  |  |  |             fname = os.path.join(directory, name) | 
					
						
							| 
									
										
										
										
											2009-05-05 18:55:47 +00:00
										 |  |  |             if os.path.isfile(fname): | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |                 return fname | 
					
						
							|  |  |  |             if fname.lower().endswith(".dll"): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             fname = fname + ".dll" | 
					
						
							| 
									
										
										
										
											2009-05-05 18:55:47 +00:00
										 |  |  |             if os.path.isfile(fname): | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |                 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) | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |         cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; 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) | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 trace = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 rv = 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 | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |         if rv == 10: | 
					
						
							|  |  |  |             raise OSError, 'gcc or cc command not found' | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  |         res = re.search(expr, trace) | 
					
						
							|  |  |  |         if not res: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return res.group(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-14 19:40:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if sys.platform == "sunos5": | 
					
						
							|  |  |  |         # use /usr/ccs/bin/dump on solaris | 
					
						
							|  |  |  |         def _get_soname(f): | 
					
						
							|  |  |  |             if not f: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             f = os.popen(cmd) | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 f.close() | 
					
						
							|  |  |  |             res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data) | 
					
						
							| 
									
										
										
										
											2007-09-14 19:40:35 +00:00
										 |  |  |             if not res: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             return res.group(1) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         def _get_soname(f): | 
					
						
							|  |  |  |             # assuming GNU binutils / ELF | 
					
						
							|  |  |  |             if not f: | 
					
						
							|  |  |  |                 return None | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |             cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ | 
					
						
							|  |  |  |                   "objdump -p -j .dynamic 2>/dev/null " + f | 
					
						
							|  |  |  |             f = os.popen(cmd) | 
					
						
							|  |  |  |             dump = f.read() | 
					
						
							|  |  |  |             rv = f.close() | 
					
						
							|  |  |  |             if rv == 10: | 
					
						
							|  |  |  |                 raise OSError, 'objdump command not found' | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             f = os.popen(cmd) | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 f.close() | 
					
						
							|  |  |  |             res = re.search(r'\sSONAME\s+([^\s]+)', data) | 
					
						
							| 
									
										
										
										
											2007-09-14 19:40:35 +00:00
										 |  |  |             if not res: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             return res.group(1) | 
					
						
							| 
									
										
										
										
											2006-05-12 18:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             f = os.popen('/sbin/ldconfig -r 2>/dev/null') | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 f.close() | 
					
						
							|  |  |  |             res = re.findall(expr, data) | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |             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) | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             f = os.popen('/sbin/ldconfig -p 2>/dev/null') | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 f.close() | 
					
						
							|  |  |  |             res = re.search(expr, data) | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |             if not res: | 
					
						
							|  |  |  |                 # Hm, this works only for libs needed by the python executable. | 
					
						
							|  |  |  |                 cmd = 'ldd %s 2>/dev/null' % sys.executable | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |                 f = os.popen(cmd) | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     data = f.read() | 
					
						
							|  |  |  |                 finally: | 
					
						
							|  |  |  |                     f.close() | 
					
						
							|  |  |  |                 res = re.search(expr, data) | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |                 if not res: | 
					
						
							|  |  |  |                     return None | 
					
						
							|  |  |  |             return res.group(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |         def _findSoname_ldconfig(name): | 
					
						
							|  |  |  |             import struct | 
					
						
							|  |  |  |             if struct.calcsize('l') == 4: | 
					
						
							|  |  |  |                 machine = os.uname()[4] + '-32' | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 machine = os.uname()[4] + '-64' | 
					
						
							|  |  |  |             mach_map = { | 
					
						
							|  |  |  |                 'x86_64-64': 'libc6,x86-64', | 
					
						
							|  |  |  |                 'ppc64-64': 'libc6,64bit', | 
					
						
							|  |  |  |                 'sparc64-64': 'libc6,64bit', | 
					
						
							|  |  |  |                 's390x-64': 'libc6,64bit', | 
					
						
							|  |  |  |                 'ia64-64': 'libc6,IA-64', | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             abi_type = mach_map.get(machine, 'libc6') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # XXX assuming GLIBC's ldconfig (with option -p) | 
					
						
							|  |  |  |             expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ | 
					
						
							|  |  |  |                    % (abi_type, re.escape(name)) | 
					
						
							| 
									
										
										
										
											2009-10-22 20:13:14 +00:00
										 |  |  |             f = os.popen('/sbin/ldconfig -p 2>/dev/null') | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = f.read() | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 f.close() | 
					
						
							|  |  |  |             res = re.search(expr, data) | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |             if not res: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             return res.group(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-12 20:17:34 +00:00
										 |  |  |         def find_library(name): | 
					
						
							| 
									
										
										
										
											2009-01-10 17:00:42 +00:00
										 |  |  |             return _findSoname_ldconfig(name) or _get_soname(_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() |