util.py revision e67474725b5b13b48ba0007e89314214a6bdca0b
1477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersimport sys, os
25ccfa29f04c6e16d6a4fd990972fb96f77d0a969Eric Smithimport contextlib
38c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrouimport subprocess
4477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
5477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters# find_library(name) returns the pathname of a library, or None.
6477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif os.name == "nt":
73eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller
83eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller    def _get_build_version():
93eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        """Return the version of MSVC that was used to build Python.
103eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller
113eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        For Python 2.3 and up, the version number is included in
123eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        sys.version.  For earlier versions, assume the compiler is MSVC 6.
133eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        """
143eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        # This function was copied from Lib/distutils/msvccompiler.py
153eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        prefix = "MSC v."
163eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        i = sys.version.find(prefix)
173eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if i == -1:
183eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            return 6
193eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        i = i + len(prefix)
203eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        s, rest = sys.version[i:].split(" ", 1)
213eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        majorVersion = int(s[:-2]) - 6
223eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        minorVersion = int(s[2:3]) / 10.0
233eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        # I don't think paths are affected by minor version in version 6
243eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if majorVersion == 6:
253eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            minorVersion = 0
263eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if majorVersion >= 6:
273eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            return majorVersion + minorVersion
283eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        # else we don't know what version of the compiler this is
293eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        return None
303eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller
313eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller    def find_msvcrt():
323eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        """Return the name of the VC runtime dll"""
333eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        version = _get_build_version()
343eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if version is None:
353eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            # better be safe than sorry
363eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            return None
373eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if version <= 6:
383eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            clibname = 'msvcrt'
393eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        else:
403eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            clibname = 'msvcr%d' % (version * 10)
413eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller
423eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        # If python was built with in debug mode
433eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        import imp
443eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if imp.get_suffixes()[0][0] == '_d.pyd':
453eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            clibname += 'd'
463eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        return clibname+'.dll'
473eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller
48477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def find_library(name):
493eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller        if name in ('c', 'm'):
503eaaeb437f7283ef60ead8464d8da6bfac4f93aaThomas Heller            return find_msvcrt()
51477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        # See MSDN for the REAL search order.
52477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        for directory in os.environ['PATH'].split(os.pathsep):
53477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            fname = os.path.join(directory, name)
5400cfc379d66c056ed5ac5a9df5b75c86f3fc7fbeThomas Heller            if os.path.isfile(fname):
55477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                return fname
56477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            if fname.lower().endswith(".dll"):
57477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                continue
58477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            fname = fname + ".dll"
5900cfc379d66c056ed5ac5a9df5b75c86f3fc7fbeThomas Heller            if os.path.isfile(fname):
60477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                return fname
61477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        return None
62477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
63477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif os.name == "ce":
64477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # search path according to MSDN:
65477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # - absolute path specified by filename
66477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # - The .exe launch directory
67477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # - the Windows directory
68477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # - ROM dll files (where are they?)
69477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # - OEM specified search path: HKLM\Loader\SystemPath
70477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def find_library(name):
71477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        return name
72477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
73477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif os.name == "posix" and sys.platform == "darwin":
74477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    from ctypes.macholib.dyld import dyld_find as _dyld_find
75477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def find_library(name):
76477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        possible = ['lib%s.dylib' % name,
77477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                    '%s.dylib' % name,
78477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                    '%s.framework/%s' % (name, name)]
79477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        for name in possible:
80477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            try:
81477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                return _dyld_find(name)
82477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            except ValueError:
83477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters                continue
84477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        return None
85477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
86477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouterselif os.name == "posix":
87477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
880e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters    import re, tempfile, errno
89477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
90477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def _findLib_gcc(name):
91fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
920e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        fdout, ccout = tempfile.mkstemp()
930e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        os.close(fdout)
942c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose        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;' \
950e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters              '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name
96477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        try:
97fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            f = os.popen(cmd)
98f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum            try:
99f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum                trace = f.read()
100f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum            finally:
1012c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                rv = f.close()
102477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        finally:
103477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            try:
1040e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                os.unlink(ccout)
105b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum            except OSError as e:
1060e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                if e.errno != errno.ENOENT:
1070e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                    raise
1082c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose        if rv == 10:
10917bf0825bddf7ffb780ac4d96f98b1b2ea1d76c5Benjamin Peterson            raise OSError('gcc or cc command not found')
110477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        res = re.search(expr, trace)
111477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        if not res:
112477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            return None
113477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        return res.group(0)
114477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
1151b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters
1161b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    if sys.platform == "sunos5":
1171b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        # use /usr/ccs/bin/dump on solaris
1181b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        def _get_soname(f):
1191b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            if not f:
1201b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters                return None
1211b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f
1225ccfa29f04c6e16d6a4fd990972fb96f77d0a969Eric Smith            with contextlib.closing(os.popen(cmd)) as f:
123f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum                data = f.read()
124f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum            res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data)
1251b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            if not res:
1261b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters                return None
1271b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            return res.group(1)
1281b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    else:
1291b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        def _get_soname(f):
1301b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            # assuming GNU binutils / ELF
1311b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            if not f:
1321b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters                return None
1332c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \
1342c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                  "objdump -p -j .dynamic 2>/dev/null " + f
1352c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            f = os.popen(cmd)
1362c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            dump = f.read()
1372c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            rv = f.close()
1382c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            if rv == 10:
13917bf0825bddf7ffb780ac4d96f98b1b2ea1d76c5Benjamin Peterson                raise OSError('objdump command not found')
140b46004c94f59af1adc081d2a89d9e3f73998ee59Antoine Pitrou            res = re.search(r'\sSONAME\s+([^\s]+)', dump)
1411b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            if not res:
1421b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters                return None
1431b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters            return res.group(1)
144477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
145e67474725b5b13b48ba0007e89314214a6bdca0bVictor Stinner    if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):
146fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
147fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        def _num_version(libname):
148fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
149fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            parts = libname.split(".")
150fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            nums = []
151fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            try:
152fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                while parts:
153fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                    nums.insert(0, int(parts.pop()))
154fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            except ValueError:
155fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                pass
156a37d4c693a024154093b36a612810c3bd72d9254Christian Heimes            return nums or [ sys.maxsize ]
157fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
158fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        def find_library(name):
159fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            ename = re.escape(name)
160fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
1615ccfa29f04c6e16d6a4fd990972fb96f77d0a969Eric Smith            with contextlib.closing(os.popen('/sbin/ldconfig -r 2>/dev/null')) as f:
162f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum                data = f.read()
163f4d4f8b97fc2e5a59058c54abe6a23194c3d3116Guido van Rossum            res = re.findall(expr, data)
164fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            if not res:
165fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                return _get_soname(_findLib_gcc(name))
166d4cb56d4e88c7e001bbaba2c80953db47632f199Raymond Hettinger            res.sort(key=_num_version)
167fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            return res[-1]
168fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
169fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
170fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1712c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose        def _findSoname_ldconfig(name):
1722c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            import struct
1732c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            if struct.calcsize('l') == 4:
1742c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                machine = os.uname()[4] + '-32'
1752c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            else:
1762c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                machine = os.uname()[4] + '-64'
1772c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            mach_map = {
1782c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                'x86_64-64': 'libc6,x86-64',
1792c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                'ppc64-64': 'libc6,64bit',
1802c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                'sparc64-64': 'libc6,64bit',
1812c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                's390x-64': 'libc6,64bit',
1822c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                'ia64-64': 'libc6,IA-64',
1832c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose                }
1842c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            abi_type = mach_map.get(machine, 'libc6')
1852c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose
1862c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            # XXX assuming GLIBC's ldconfig (with option -p)
1878c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou            regex = os.fsencode(
1888c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                '\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type))
1898c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou            try:
1908c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                with subprocess.Popen(['/sbin/ldconfig', '-p'],
1918c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                                      stdin=subprocess.DEVNULL,
1928c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                                      stderr=subprocess.DEVNULL,
1938c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                                      stdout=subprocess.PIPE,
1948c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                                      env={'LC_ALL': 'C', 'LANG': 'C'}) as p:
1958c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                    res = re.search(regex, p.stdout.read())
1968c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                    if res:
1978c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                        return os.fsdecode(res.group(1))
1988c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou            except OSError:
1998c52027e2d8c4268d0d0e376948d3107576a4aa4Antoine Pitrou                pass
2002c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose
201fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        def find_library(name):
2022c7e3ee79b0a9bbcf0d67a3d788b31392e14dc15Matthias Klose            return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name))
203477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
204477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters################################################################
205477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters# test code
206477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
207477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersdef test():
208477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    from ctypes import cdll
209477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    if os.name == "nt":
210be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(cdll.msvcrt)
211be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(cdll.load("msvcrt"))
212be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(find_library("msvcrt"))
213477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
214477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    if os.name == "posix":
215477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        # find and load_version
216be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(find_library("m"))
217be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(find_library("c"))
218be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        print(find_library("bz2"))
219477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
220477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        # getattr
221477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters##        print cdll.m
222477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters##        print cdll.bz2
223477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
224477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        # load
225477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        if sys.platform == "darwin":
226be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("libm.dylib"))
227be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("libcrypto.dylib"))
228be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("libSystem.dylib"))
229be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("System.framework/System"))
230477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        else:
231be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("libm.so"))
232be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(cdll.LoadLibrary("libcrypt.so"))
233be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum            print(find_library("crypt"))
234477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
235477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersif __name__ == "__main__":
236477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    test()
237