diff -r 44a382d49e86 -r ce3be1c1091a Lib/ctypes/test/test_find.py --- a/Lib/ctypes/test/test_find.py Mon Jun 04 00:32:15 2012 -0700 +++ b/Lib/ctypes/test/test_find.py Mon Jun 04 22:07:00 2012 +0100 @@ -1,4 +1,5 @@ import unittest +import os import sys from ctypes import * from ctypes.util import find_library @@ -55,6 +56,57 @@ if self.gle: self.gle.gleGetJoinStyle + +@unittest.skipUnless(sys.platform.startswith('linux'), + 'Test only valid for Linux') +class LibPathFindTest(unittest.TestCase): + def test_find_on_libpath(self): + import subprocess + import tempfile + + p = subprocess.Popen(['gcc', '--version'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, _ = p.communicate() + if p.returncode != 0: + raise unittest.SkipTest('gcc, needed for test, not available') + with tempfile.TemporaryDirectory() as d: + # create an empty temporary file + srcname = os.path.join(d, 'dummy.c') + dstname = os.path.join(d, 'libdummy.so') + with open(srcname, 'w') as f: + pass + self.assertTrue(os.path.exists(srcname)) + # compile the file to a shared library + cmd = ['gcc', '-o', dstname, '--shared', + '-Wl,-soname,libdummy.so', srcname] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, _ = p.communicate() + self.assertEqual(p.returncode, 0) + self.assertTrue(os.path.exists(dstname)) + # now check that libdummy.so can't be found (since not in + # LD_LIBRARY_PATH) + self.assertTrue(find_library('dummy') is None) + # now add the location to LD_LIBRARY_PATH + KEY = 'LD_LIBRARY_PATH' + if KEY not in os.environ: + existed = False + os.environ[KEY] = d + else: + existed = True + old_path = os.environ[KEY] + os.environ[KEY] = '%s:%s' % (old_path, d) + try: + # now check that libdummy.so can be found (since in + # LD_LIBRARY_PATH) + self.assertTrue(find_library('dummy') == 'libdummy.so') + finally: + # restore environment + if not existed: + del os.environ[KEY] + else: + os.environ[KEY] = old_path + ##if os.name == "posix" and sys.platform != "darwin": ## # On platforms where the default shared library suffix is '.so', diff -r 44a382d49e86 -r ce3be1c1091a Lib/ctypes/util.py --- a/Lib/ctypes/util.py Mon Jun 04 00:32:15 2012 -0700 +++ b/Lib/ctypes/util.py Mon Jun 04 22:07:00 2012 +0100 @@ -88,29 +88,25 @@ import re, tempfile, errno def _findLib_gcc(name): + # Use ld instead of gcc. See comment for Issue #11959. 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; 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) - try: - trace = f.read() - finally: - rv = f.close() - finally: - try: - os.unlink(ccout) - except OSError as e: - if e.errno != errno.ENOENT: - raise - if rv == 10: - raise OSError('gcc or cc command not found') - res = re.search(expr, trace) + cmd = ['ld', '-t'] + libpath = os.environ.get('LD_LIBRARY_PATH') + if libpath: + for d in libpath.split(':'): + cmd.extend(['-L', d]) + cmd.extend(['-o', os.devnull, '-l%s' % name]) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=os.environ) + out, _ = p.communicate() + import locale + encoding = locale.getpreferredencoding() + res = re.search(expr, out.decode(encoding)) if not res: - return None - return res.group(0) + result = None + else: + result = res.group(0) + return result if sys.platform == "sunos5":