summaryrefslogtreecommitdiff
path: root/pipermail/pycrypto/attachments/20110926/cbc2b92a/attachment-0001.patch
blob: 5db2b152a1e6ecffd1fedacf03cb5f5b68412e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
--- setup.py.orig       2011-09-25 22:04:15.000000000 +0000
+++ setup.py    2011-09-25 22:10:55.000000000 +0000
@@ -39,6 +39,10 @@
 from distutils import core
 from distutils.core import Extension, Command
 from distutils.command.build_ext import build_ext
+from distutils.errors import CompileError, LinkError
+import distutils.ccompiler
+import distutils.sysconfig
+import tempfile
 import os, sys
 import struct
 
@@ -69,42 +73,33 @@
     ('Crypto.Hash', 'RIPEMD160'),  # Included for your amusement, but the C version is much faster.
 ]
 
-# Functions for finding libraries and files, copied from Python's setup.py.
-
-def find_file(filename, std_dirs, paths):
-    """Searches for the directory where a given file is located,
-    and returns a possibly-empty list of additional directories, or None
-    if the file couldn't be found at all.
-
-    'filename' is the name of a file, such as readline.h or libcrypto.a.
-    'std_dirs' is the list of standard system directories; if the
-        file is found in one of them, no additional directives are needed.
-    'paths' is a list of additional locations to check; if the file is
-        found in one of them, the resulting list will contain the directory.
-    """
-
-    # Check the standard locations
-    for dir in std_dirs:
-        f = os.path.join(dir, filename)
-        if os.path.exists(f): return []
-
-    # Check the additional directories
-    for dir in paths:
-        f = os.path.join(dir, filename)
-        if os.path.exists(f):
-            return [dir]
-
-    # Not found anywhere
-    return None
-
-def find_library_file(compiler, libname, std_dirs, paths):
-    filename = compiler.library_filename(libname, lib_type='shared')
-    result = find_file(filename, std_dirs, paths)
-    if result is not None: return result
-
-    filename = compiler.library_filename(libname, lib_type='static')
-    result = find_file(filename, std_dirs, paths)
-    return result
+def libgmp_exists():
+    fname = tempfile.mktemp(".c")
+    oname = tempfile.mktemp(".out")
+    f = open(fname, 'w')
+    f.write("""
+    #include <gmp.h>
+
+    int main(void)
+    {
+        mpz_init((void*)0);
+        return 0;
+    }
+    """)
+    f.close()
+
+    try:
+        compiler = distutils.ccompiler.new_compiler()
+        distutils.sysconfig.customize_compiler(compiler)
+        objects = compiler.compile([fname])
+        compiler.link_shared_object(objects, oname, libraries=('gmp',) )
+    except (CompileError, LinkError, TypeError):
+        os.remove(fname)
+        return False
+    os.remove(oname)
+    os.remove(objects[0])
+    os.remove(fname)
+    return True
 
 def endianness_macro():
     s = struct.pack("@I", 0x33221100)
@@ -157,8 +152,7 @@
             self.compiler.include_dirs.insert(0, "src/inc-msvc/")
 
         # Detect libgmp and don't build _fastmath if it is missing.
-        lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
-        if not (self.compiler.find_library_file(lib_dirs, 'gmp')):
+        if not libgmp_exists():
             print >>sys.stderr, "warning: GMP library not found; Not building Crypto.PublicKey._fastmath."
             self.__remove_extensions(["Crypto.PublicKey._fastmath"])