1 ######################################################################
2 # This file should be kept compatible with Python 2.3, see PEP 291. #
3 ######################################################################
6 # find_library(name) returns the pathname of a library, or None.
9 def _get_build_version():
10 """Return the version of MSVC that was used to build Python.
12 For Python 2.3 and up, the version number is included in
13 sys.version. For earlier versions, assume the compiler is MSVC 6.
15 # This function was copied from Lib/distutils/msvccompiler.py
17 i
= sys
.version
.find(prefix
)
21 s
, rest
= sys
.version
[i
:].split(" ", 1)
22 majorVersion
= int(s
[:-2]) - 6
23 minorVersion
= int(s
[2:3]) / 10.0
24 # I don't think paths are affected by minor version in version 6
28 return majorVersion
+ minorVersion
29 # else we don't know what version of the compiler this is
33 """Return the name of the VC runtime dll"""
34 version
= _get_build_version()
36 # better be safe than sorry
41 clibname
= 'msvcr%d' % (version
* 10)
43 # If python was built with in debug mode
45 if imp
.get_suffixes()[0][0] == '_d.pyd':
47 return clibname
+'.dll'
49 def find_library(name
):
50 if name
in ('c', 'm'):
52 # See MSDN for the REAL search order.
53 for directory
in os
.environ
['PATH'].split(os
.pathsep
):
54 fname
= os
.path
.join(directory
, name
)
55 if os
.path
.isfile(fname
):
57 if fname
.lower().endswith(".dll"):
59 fname
= fname
+ ".dll"
60 if os
.path
.isfile(fname
):
65 # search path according to MSDN:
66 # - absolute path specified by filename
67 # - The .exe launch directory
68 # - the Windows directory
69 # - ROM dll files (where are they?)
70 # - OEM specified search path: HKLM\Loader\SystemPath
71 def find_library(name
):
74 if os
.name
== "posix" and sys
.platform
== "darwin":
75 from ctypes
.macholib
.dyld
import dyld_find
as _dyld_find
76 def find_library(name
):
77 possible
= ['lib%s.dylib' % name
,
79 '%s.framework/%s' % (name
, name
)]
82 return _dyld_find(name
)
87 elif os
.name
== "posix":
88 # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
89 import re
, tempfile
, errno
91 def _findLib_gcc(name
):
92 expr
= r
'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re
.escape(name
)
93 fdout
, ccout
= tempfile
.mkstemp()
95 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;' \
96 '$CC -Wl,-t -o ' + ccout
+ ' 2>&1 -l' + name
107 if e
.errno
!= errno
.ENOENT
:
110 raise OSError, 'gcc or cc command not found'
111 res
= re
.search(expr
, trace
)
117 if sys
.platform
== "sunos5":
118 # use /usr/ccs/bin/dump on solaris
122 cmd
= "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f
128 res
= re
.search(r
'\[.*\]\sSONAME\s+([^\s]+)', data
)
134 # assuming GNU binutils / ELF
137 cmd
= 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \
138 "objdump -p -j .dynamic 2>/dev/null " + f
143 raise OSError, 'objdump command not found'
149 res
= re
.search(r
'\sSONAME\s+([^\s]+)', data
)
154 if (sys
.platform
.startswith("freebsd")
155 or sys
.platform
.startswith("openbsd")
156 or sys
.platform
.startswith("dragonfly")):
158 def _num_version(libname
):
159 # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
160 parts
= libname
.split(".")
164 nums
.insert(0, int(parts
.pop()))
167 return nums
or [ sys
.maxint
]
169 def find_library(name
):
170 ename
= re
.escape(name
)
171 expr
= r
':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename
, ename
)
172 f
= os
.popen('/sbin/ldconfig -r 2>/dev/null')
177 res
= re
.findall(expr
, data
)
179 return _get_soname(_findLib_gcc(name
))
180 res
.sort(cmp= lambda x
,y
: cmp(_num_version(x
), _num_version(y
)))
185 def _findLib_ldconfig(name
):
186 # XXX assuming GLIBC's ldconfig (with option -p)
187 expr
= r
'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re
.escape(name
)
188 f
= os
.popen('LANG=C /sbin/ldconfig -p 2>/dev/null')
193 res
= re
.search(expr
, data
)
195 # Hm, this works only for libs needed by the python executable.
196 cmd
= 'ldd %s 2>/dev/null' % sys
.executable
202 res
= re
.search(expr
, data
)
207 def _findSoname_ldconfig(name
):
209 if struct
.calcsize('l') == 4:
210 machine
= os
.uname()[4] + '-32'
212 machine
= os
.uname()[4] + '-64'
214 'x86_64-64': 'libc6,x86-64',
215 'ppc64-64': 'libc6,64bit',
216 'sparc64-64': 'libc6,64bit',
217 's390x-64': 'libc6,64bit',
218 'ia64-64': 'libc6,IA-64',
220 abi_type
= mach_map
.get(machine
, 'libc6')
222 # XXX assuming GLIBC's ldconfig (with option -p)
223 expr
= r
'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \
224 % (abi_type
, re
.escape(name
))
225 f
= os
.popen('/sbin/ldconfig -p 2>/dev/null')
230 res
= re
.search(expr
, data
)
235 def find_library(name
):
236 return _findSoname_ldconfig(name
) or _get_soname(_findLib_gcc(name
))
238 ################################################################
242 from ctypes
import cdll
245 print cdll
.load("msvcrt")
246 print find_library("msvcrt")
248 if os
.name
== "posix":
249 # find and load_version
250 print find_library("m")
251 print find_library("c")
252 print find_library("bz2")
259 if sys
.platform
== "darwin":
260 print cdll
.LoadLibrary("libm.dylib")
261 print cdll
.LoadLibrary("libcrypto.dylib")
262 print cdll
.LoadLibrary("libSystem.dylib")
263 print cdll
.LoadLibrary("System.framework/System")
265 print cdll
.LoadLibrary("libm.so")
266 print cdll
.LoadLibrary("libcrypt.so")
267 print find_library("crypt")
269 if __name__
== "__main__":