1bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panterimport os 2bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panterimport shutil 38c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrouimport subprocess 4bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panterimport sys 5477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 6477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters# find_library(name) returns the pathname of a library, or None. 7477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif os.name == "nt": 83eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller 93eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller def _get_build_version(): 103eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller """Return the version of MSVC that was used to build Python. 113eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller 123eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller For Python 2.3 and up, the version number is included in 133eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller sys.version. For earlier versions, assume the compiler is MSVC 6. 143eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller """ 153eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller # This function was copied from Lib/distutils/msvccompiler.py 163eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller prefix = "MSC v." 173eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller i = sys.version.find(prefix) 183eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if i == -1: 193eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return 6 203eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller i = i + len(prefix) 213eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller s, rest = sys.version[i:].split(" ", 1) 223eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller majorVersion = int(s[:-2]) - 6 2365e4cb10d9d9964f30bc72561bf0e86833328a3bSteve Dower if majorVersion >= 13: 2465e4cb10d9d9964f30bc72561bf0e86833328a3bSteve Dower majorVersion += 1 253eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller minorVersion = int(s[2:3]) / 10.0 263eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller # I don't think paths are affected by minor version in version 6 273eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if majorVersion == 6: 283eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller minorVersion = 0 293eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if majorVersion >= 6: 303eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return majorVersion + minorVersion 313eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller # else we don't know what version of the compiler this is 323eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return None 333eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller 343eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller def find_msvcrt(): 353eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller """Return the name of the VC runtime dll""" 363eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller version = _get_build_version() 373eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if version is None: 383eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller # better be safe than sorry 393eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return None 403eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if version <= 6: 413eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller clibname = 'msvcrt' 4265e4cb10d9d9964f30bc72561bf0e86833328a3bSteve Dower elif version <= 13: 433eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller clibname = 'msvcr%d' % (version * 10) 4465e4cb10d9d9964f30bc72561bf0e86833328a3bSteve Dower else: 45959ee7c200373e77cae445283016f2827147e96aSteve Dower # CRT is no longer directly loadable. See issue23606 for the 46959ee7c200373e77cae445283016f2827147e96aSteve Dower # discussion about alternative approaches. 47959ee7c200373e77cae445283016f2827147e96aSteve Dower return None 483eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller 493eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller # If python was built with in debug mode 50cb66eb0deca1d5cd232f97c76a215ecaab958d30Brett Cannon import importlib.machinery 51cb66eb0deca1d5cd232f97c76a215ecaab958d30Brett Cannon if '_d.pyd' in importlib.machinery.EXTENSION_SUFFIXES: 523eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller clibname += 'd' 533eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return clibname+'.dll' 543eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller 55477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters def find_library(name): 563eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller if name in ('c', 'm'): 573eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller return find_msvcrt() 58477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters # See MSDN for the REAL search order. 59477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters for directory in os.environ['PATH'].split(os.pathsep): 60477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters fname = os.path.join(directory, name) 6100cfc379d66c056ed5ac5a9df5b75c86f3fc7fbeThomas Heller if os.path.isfile(fname): 62477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return fname 63477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters if fname.lower().endswith(".dll"): 64477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters continue 65477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters fname = fname + ".dll" 6600cfc379d66c056ed5ac5a9df5b75c86f3fc7fbeThomas Heller if os.path.isfile(fname): 67477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return fname 68477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return None 69477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 70477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif os.name == "posix" and sys.platform == "darwin": 71477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters from ctypes.macholib.dyld import dyld_find as _dyld_find 72477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters def find_library(name): 73477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters possible = ['lib%s.dylib' % name, 74477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters '%s.dylib' % name, 75477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters '%s.framework/%s' % (name, name)] 76477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters for name in possible: 77477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters try: 78477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return _dyld_find(name) 79477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters except ValueError: 80477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters continue 81477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return None 82477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 83477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouterselif os.name == "posix": 84477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump 857fa767e517882f4d3503d168d3a4d4caad317752Victor Stinner import re, tempfile 86477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 87477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters def _findLib_gcc(name): 88bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # Run GCC's linker with the -t (aka --trace) option and examine the 89bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # library name it prints out. The GCC command will fail because we 90bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # haven't supplied a proper program with main(), but that does not 91bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # matter. 92bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)) 93bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 94bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter c_compiler = shutil.which('gcc') 95bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter if not c_compiler: 96bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter c_compiler = shutil.which('cc') 97bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter if not c_compiler: 98bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # No C compiler available, give up 99bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return None 100bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 101bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter temp = tempfile.NamedTemporaryFile() 102477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters try: 103bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name] 104bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 105bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter env = dict(os.environ) 106bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter env['LC_ALL'] = 'C' 107bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter env['LANG'] = 'C' 108e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter try: 109e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter proc = subprocess.Popen(args, 110e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stdout=subprocess.PIPE, 111e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stderr=subprocess.STDOUT, 112e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter env=env) 113e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter except OSError: # E.g. bad executable 114e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter return None 115bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter with proc: 116bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter trace = proc.stdout.read() 117477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters finally: 118477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters try: 119bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter temp.close() 1200166a283f65b08ee2dddb1b075f86862b8c7e3e4Giampaolo Rodola' except FileNotFoundError: 121bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # Raised if the file was already removed, which is the normal 122bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # behaviour of GCC if linking fails 1230166a283f65b08ee2dddb1b075f86862b8c7e3e4Giampaolo Rodola' pass 124477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters res = re.search(expr, trace) 125477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters if not res: 126477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters return None 127bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return os.fsdecode(res.group(0)) 128477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 1291b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters 1301b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if sys.platform == "sunos5": 1311b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters # use /usr/ccs/bin/dump on solaris 1321b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters def _get_soname(f): 1331b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if not f: 1341b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters return None 135bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 136e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter try: 137e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f), 138e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stdout=subprocess.PIPE, 139e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stderr=subprocess.DEVNULL) 140e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter except OSError: # E.g. command not found 141e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter return None 142bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter with proc: 143bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter data = proc.stdout.read() 144bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter res = re.search(br'\[.*\]\sSONAME\s+([^\s]+)', data) 1451b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if not res: 1461b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters return None 147bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return os.fsdecode(res.group(1)) 1481b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters else: 1491b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters def _get_soname(f): 1501b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters # assuming GNU binutils / ELF 1511b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if not f: 1521b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters return None 153bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter objdump = shutil.which('objdump') 154bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter if not objdump: 155bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter # objdump is not available, give up 156bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return None 157bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 158e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter try: 159e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter proc = subprocess.Popen((objdump, '-p', '-j', '.dynamic', f), 160e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stdout=subprocess.PIPE, 161e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stderr=subprocess.DEVNULL) 162e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter except OSError: # E.g. bad executable 163e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter return None 164bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter with proc: 165bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter dump = proc.stdout.read() 166bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter res = re.search(br'\sSONAME\s+([^\s]+)', dump) 1671b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if not res: 1681b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters return None 169bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return os.fsdecode(res.group(1)) 170477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 171e67474725b5b13b48ba0007e89314214a6bdca0bVictor Stinner if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")): 172fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 173fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters def _num_version(libname): 174fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] 175bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter parts = libname.split(b".") 176fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters nums = [] 177fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters try: 178fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters while parts: 179fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters nums.insert(0, int(parts.pop())) 180fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters except ValueError: 181fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters pass 182bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return nums or [sys.maxsize] 183fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 184fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters def find_library(name): 185fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters ename = re.escape(name) 186fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) 187bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter expr = os.fsencode(expr) 188bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 189e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter try: 190e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter proc = subprocess.Popen(('/sbin/ldconfig', '-r'), 191e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stdout=subprocess.PIPE, 192e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stderr=subprocess.DEVNULL) 193e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter except OSError: # E.g. command not found 194e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter data = b'' 195e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter else: 196e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter with proc: 197e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter data = proc.stdout.read() 198bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 199f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum res = re.findall(expr, data) 200fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if not res: 201fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _get_soname(_findLib_gcc(name)) 202d4cb56d4e88c7e001bbaba2c80953db47632f199Raymond Hettinger res.sort(key=_num_version) 203bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter return os.fsdecode(res[-1]) 204fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 205cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson elif sys.platform == "sunos5": 206cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 207cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson def _findLib_crle(name, is64): 208cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson if not os.path.exists('/usr/bin/crle'): 209cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson return None 210cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 211bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter env = dict(os.environ) 212bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter env['LC_ALL'] = 'C' 213bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter 214cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson if is64: 215bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter args = ('/usr/bin/crle', '-64') 216cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson else: 217bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter args = ('/usr/bin/crle',) 218cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 2198988ebf2a7a89620781feca39074f91469e7baf2Meador Inge paths = None 220e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter try: 221e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter proc = subprocess.Popen(args, 222e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stdout=subprocess.PIPE, 223e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter stderr=subprocess.DEVNULL, 224e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter env=env) 225e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter except OSError: # E.g. bad executable 226e1b3431cef4873b2853199f4b5114de7e26de998Martin Panter return None 227bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter with proc: 228bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter for line in proc.stdout: 2291889623e1a49e38df6d10171e4a4256dfcb8916bNick Coghlan line = line.strip() 230bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter if line.startswith(b'Default Library Path (ELF):'): 231bfb15ab71165ccdf65ed1243e80e7e293999f034Martin Panter paths = os.fsdecode(line).split()[4] 232cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 233cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson if not paths: 234cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson return None 235cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 236cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson for dir in paths.split(":"): 237cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson libfile = os.path.join(dir, "lib%s.so" % name) 238cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson if os.path.exists(libfile): 239cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson return libfile 240cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 241cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson return None 242cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 243cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson def find_library(name, is64 = False): 244cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name)) 245cfe34744e3c785a56525ab8a9473336206f5854dBenjamin Peterson 246fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters else: 247fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 2482c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose def _findSoname_ldconfig(name): 2492c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose import struct 2502c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose if struct.calcsize('l') == 4: 251605a62ddb1c19978ee194a40a458f072e3242a31Larry Hastings machine = os.uname().machine + '-32' 2522c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose else: 253605a62ddb1c19978ee194a40a458f072e3242a31Larry Hastings machine = os.uname().machine + '-64' 2542c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose mach_map = { 2552c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 'x86_64-64': 'libc6,x86-64', 2562c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 'ppc64-64': 'libc6,64bit', 2572c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 'sparc64-64': 'libc6,64bit', 2582c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 's390x-64': 'libc6,64bit', 2592c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 'ia64-64': 'libc6,IA-64', 2602c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose } 2612c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose abi_type = mach_map.get(machine, 'libc6') 2622c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 2632c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose # XXX assuming GLIBC's ldconfig (with option -p) 26432f2eb4941db115d4d5d0902ba086820406ef4b2Martin Panter regex = r'\s+(lib%s\.[^\s]+)\s+\(%s' 265b9f3114d42601b07c9830af8b18330bff475bcfcMartin Panter regex = os.fsencode(regex % (re.escape(name), abi_type)) 2668c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou try: 2678c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou with subprocess.Popen(['/sbin/ldconfig', '-p'], 2688c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou stdin=subprocess.DEVNULL, 2698c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou stderr=subprocess.DEVNULL, 2708c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou stdout=subprocess.PIPE, 2718c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou env={'LC_ALL': 'C', 'LANG': 'C'}) as p: 2728c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou res = re.search(regex, p.stdout.read()) 2738c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou if res: 2748c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou return os.fsdecode(res.group(1)) 2758c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou except OSError: 2768c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou pass 2772c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose 27882df3b3071bb003247c33eac4670775e9883c994Vinay Sajip def _findLib_ld(name): 27982df3b3071bb003247c33eac4670775e9883c994Vinay Sajip # See issue #9998 for why this is needed 28082df3b3071bb003247c33eac4670775e9883c994Vinay Sajip expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) 28182df3b3071bb003247c33eac4670775e9883c994Vinay Sajip cmd = ['ld', '-t'] 28282df3b3071bb003247c33eac4670775e9883c994Vinay Sajip libpath = os.environ.get('LD_LIBRARY_PATH') 28382df3b3071bb003247c33eac4670775e9883c994Vinay Sajip if libpath: 28482df3b3071bb003247c33eac4670775e9883c994Vinay Sajip for d in libpath.split(':'): 28582df3b3071bb003247c33eac4670775e9883c994Vinay Sajip cmd.extend(['-L', d]) 28682df3b3071bb003247c33eac4670775e9883c994Vinay Sajip cmd.extend(['-o', os.devnull, '-l%s' % name]) 28782df3b3071bb003247c33eac4670775e9883c994Vinay Sajip result = None 28882df3b3071bb003247c33eac4670775e9883c994Vinay Sajip try: 28982df3b3071bb003247c33eac4670775e9883c994Vinay Sajip p = subprocess.Popen(cmd, stdout=subprocess.PIPE, 29082df3b3071bb003247c33eac4670775e9883c994Vinay Sajip stderr=subprocess.PIPE, 29182df3b3071bb003247c33eac4670775e9883c994Vinay Sajip universal_newlines=True) 29282df3b3071bb003247c33eac4670775e9883c994Vinay Sajip out, _ = p.communicate() 29382df3b3071bb003247c33eac4670775e9883c994Vinay Sajip res = re.search(expr, os.fsdecode(out)) 29482df3b3071bb003247c33eac4670775e9883c994Vinay Sajip if res: 29582df3b3071bb003247c33eac4670775e9883c994Vinay Sajip result = res.group(0) 29682df3b3071bb003247c33eac4670775e9883c994Vinay Sajip except Exception as e: 29782df3b3071bb003247c33eac4670775e9883c994Vinay Sajip pass # result will be None 29882df3b3071bb003247c33eac4670775e9883c994Vinay Sajip return result 29982df3b3071bb003247c33eac4670775e9883c994Vinay Sajip 300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters def find_library(name): 30182df3b3071bb003247c33eac4670775e9883c994Vinay Sajip # See issue #9998 30282df3b3071bb003247c33eac4670775e9883c994Vinay Sajip return _findSoname_ldconfig(name) or \ 30382df3b3071bb003247c33eac4670775e9883c994Vinay Sajip _get_soname(_findLib_gcc(name) or _findLib_ld(name)) 304477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 305477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters################################################################ 306477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters# test code 307477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 308477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersdef test(): 309477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters from ctypes import cdll 310477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters if os.name == "nt": 311be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.msvcrt) 312be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.load("msvcrt")) 313be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(find_library("msvcrt")) 314477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 315477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters if os.name == "posix": 316477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters # find and load_version 317be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(find_library("m")) 318be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(find_library("c")) 319be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(find_library("bz2")) 320477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 321477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters # getattr 322477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters## print cdll.m 323477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters## print cdll.bz2 324477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 325477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters # load 326477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters if sys.platform == "darwin": 327be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("libm.dylib")) 328be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("libcrypto.dylib")) 329be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("libSystem.dylib")) 330be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("System.framework/System")) 331477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters else: 332be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("libm.so")) 333be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(cdll.LoadLibrary("libcrypt.so")) 334be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print(find_library("crypt")) 335477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters 336477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif __name__ == "__main__": 337477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters test() 338