diff options
author | Matthias Klose <doko@ubuntu.com> | 2009-01-10 17:00:42 (GMT) |
---|---|---|
committer | Matthias Klose <doko@ubuntu.com> | 2009-01-10 17:00:42 (GMT) |
commit | 43723e2ad81599b54172a5dcc48790e51ff64f5f (patch) | |
tree | 3c923c948e8330ce291910765a7eba5d1cca73b0 /Lib | |
parent | bd4b5f2b874061ae32fbc692a16c7323a5e2a377 (diff) | |
download | cpython-43723e2ad81599b54172a5dcc48790e51ff64f5f.zip cpython-43723e2ad81599b54172a5dcc48790e51ff64f5f.tar.gz cpython-43723e2ad81599b54172a5dcc48790e51ff64f5f.tar.bz2 |
- Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on
biarch systems. Try to rely on ldconfig only, without using objdump and gcc.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/ctypes/util.py | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 82ff662..433d0d9 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -92,18 +92,20 @@ elif os.name == "posix": expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) fdout, ccout = tempfile.mkstemp() os.close(fdout) - cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \ + 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;' \ '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name try: f = os.popen(cmd) trace = f.read() - f.close() + rv = f.close() finally: try: os.unlink(ccout) except OSError, e: if e.errno != errno.ENOENT: raise + if rv == 10: + raise OSError, 'gcc or cc command not found' res = re.search(expr, trace) if not res: return None @@ -125,7 +127,13 @@ elif os.name == "posix": # assuming GNU binutils / ELF if not f: return None - cmd = "objdump -p -j .dynamic 2>/dev/null " + f + 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' res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read()) if not res: return None @@ -171,8 +179,32 @@ elif os.name == "posix": return None return res.group(0) + 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)) + res = re.search(expr, + os.popen('/sbin/ldconfig -p 2>/dev/null').read()) + if not res: + return None + return res.group(1) + def find_library(name): - return _get_soname(_findLib_ldconfig(name) or _findLib_gcc(name)) + return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) ################################################################ # test code |