blob: 2ee2968d910b7cd89f0a6448feec8c22476b234a [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001######################################################################
2# This file should be kept compatible with Python 2.3, see PEP 291. #
3######################################################################
Thomas Wouters477c8d52006-05-27 19:21:47 +00004import sys, os
Thomas Wouters477c8d52006-05-27 19:21:47 +00005
6# find_library(name) returns the pathname of a library, or None.
7if os.name == "nt":
8 def find_library(name):
9 # See MSDN for the REAL search order.
10 for directory in os.environ['PATH'].split(os.pathsep):
11 fname = os.path.join(directory, name)
12 if os.path.exists(fname):
13 return fname
14 if fname.lower().endswith(".dll"):
15 continue
16 fname = fname + ".dll"
17 if os.path.exists(fname):
18 return fname
19 return None
20
21if os.name == "ce":
22 # search path according to MSDN:
23 # - absolute path specified by filename
24 # - The .exe launch directory
25 # - the Windows directory
26 # - ROM dll files (where are they?)
27 # - OEM specified search path: HKLM\Loader\SystemPath
28 def find_library(name):
29 return name
30
31if os.name == "posix" and sys.platform == "darwin":
32 from ctypes.macholib.dyld import dyld_find as _dyld_find
33 def find_library(name):
34 possible = ['lib%s.dylib' % name,
35 '%s.dylib' % name,
36 '%s.framework/%s' % (name, name)]
37 for name in possible:
38 try:
39 return _dyld_find(name)
40 except ValueError:
41 continue
42 return None
43
44elif os.name == "posix":
45 # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046 import re, tempfile, errno
Thomas Wouters477c8d52006-05-27 19:21:47 +000047
48 def _findLib_gcc(name):
49 expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050 fdout, ccout = tempfile.mkstemp()
51 os.close(fdout)
Thomas Wouters477c8d52006-05-27 19:21:47 +000052 cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053 '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
Thomas Wouters477c8d52006-05-27 19:21:47 +000054 try:
55 fdout, outfile = tempfile.mkstemp()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056 os.close(fdout)
Thomas Wouters477c8d52006-05-27 19:21:47 +000057 fd = os.popen(cmd)
58 trace = fd.read()
59 err = fd.close()
60 finally:
61 try:
62 os.unlink(outfile)
63 except OSError, e:
64 if e.errno != errno.ENOENT:
65 raise
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066 try:
67 os.unlink(ccout)
68 except OSError, e:
69 if e.errno != errno.ENOENT:
70 raise
Thomas Wouters477c8d52006-05-27 19:21:47 +000071 res = re.search(expr, trace)
72 if not res:
73 return None
74 return res.group(0)
75
76 def _findLib_ld(name):
77 expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
78 res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
79 if not res:
80 # Hm, this works only for libs needed by the python executable.
81 cmd = 'ldd %s 2>/dev/null' % sys.executable
82 res = re.search(expr, os.popen(cmd).read())
83 if not res:
84 return None
85 return res.group(0)
86
87 def _get_soname(f):
88 cmd = "objdump -p -j .dynamic 2>/dev/null " + f
89 res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
90 if not res:
91 return None
92 return res.group(1)
93
94 def find_library(name):
95 lib = _findLib_ld(name) or _findLib_gcc(name)
96 if not lib:
97 return None
98 return _get_soname(lib)
99
100################################################################
101# test code
102
103def test():
104 from ctypes import cdll
105 if os.name == "nt":
106 print cdll.msvcrt
107 print cdll.load("msvcrt")
108 print find_library("msvcrt")
109
110 if os.name == "posix":
111 # find and load_version
112 print find_library("m")
113 print find_library("c")
114 print find_library("bz2")
115
116 # getattr
117## print cdll.m
118## print cdll.bz2
119
120 # load
121 if sys.platform == "darwin":
122 print cdll.LoadLibrary("libm.dylib")
123 print cdll.LoadLibrary("libcrypto.dylib")
124 print cdll.LoadLibrary("libSystem.dylib")
125 print cdll.LoadLibrary("System.framework/System")
126 else:
127 print cdll.LoadLibrary("libm.so")
128 print cdll.LoadLibrary("libcrypt.so")
129 print find_library("crypt")
130
131if __name__ == "__main__":
132 test()