summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwayne C. Litzenberger <dlitz@dlitz.net>2011-10-10 19:14:30 -0400
committerDwayne C. Litzenberger <dlitz@dlitz.net>2011-10-10 19:15:50 -0400
commit323ce9ef951378dc96ce14c9e514e9aa19ab39d9 (patch)
tree5986ee1d95f37cdb4605b5b4899667747ae40dfc
parent32114297da2450af00c4612596bc15da4f6256f2 (diff)
downloadpycrypto-323ce9ef951378dc96ce14c9e514e9aa19ab39d9.tar.gz
Fix libgmp/libmpir autodetection
-rwxr-xr-xconfigure87
-rw-r--r--configure.ac19
-rw-r--r--setup.py62
-rw-r--r--src/_fastmath.c10
-rw-r--r--src/config.h.in7
-rw-r--r--src/inc-msvc/config.h12
6 files changed, 158 insertions, 39 deletions
diff --git a/configure b/configure
index 4e6593f..1e38c20 100755
--- a/configure
+++ b/configure
@@ -3083,13 +3083,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Checks for libraries.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for in -l" >&5
-$as_echo_n "checking for in -l... " >&6; }
-if test "${ac_cv_lib__+set}" = set; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lgmp" >&5
+$as_echo_n "checking for __gmpz_init in -lgmp... " >&6; }
+if test "${ac_cv_lib_gmp___gmpz_init+set}" = set; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-l $LIBS"
+LIBS="-lgmp $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -3099,36 +3099,87 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char ();
+char __gmpz_init ();
int
main ()
{
-return ();
+return __gmpz_init ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib__=yes
+ ac_cv_lib_gmp___gmpz_init=yes
else
- ac_cv_lib__=no
+ ac_cv_lib_gmp___gmpz_init=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib__" >&5
-$as_echo "$ac_cv_lib__" >&6; }
-if test "x$ac_cv_lib__" = x""yes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_init" >&5
+$as_echo "$ac_cv_lib_gmp___gmpz_init" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_init" = x""yes; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_LIB 1
+#define HAVE_LIBGMP 1
_ACEOF
- LIBS="-l $LIBS"
+ LIBS="-lgmp $LIBS"
fi
-ac_fn_c_check_decl "$LINENO" "mpz_powm" "ac_cv_have_decl_mpz_powm" "#include <gmp.h>
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lmpir" >&5
+$as_echo_n "checking for __gmpz_init in -lmpir... " >&6; }
+if test "${ac_cv_lib_mpir___gmpz_init+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmpir $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mpir___gmpz_init=yes
+else
+ ac_cv_lib_mpir___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpir___gmpz_init" >&5
+$as_echo "$ac_cv_lib_mpir___gmpz_init" >&6; }
+if test "x$ac_cv_lib_mpir___gmpz_init" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMPIR 1
+_ACEOF
+
+ LIBS="-lmpir $LIBS"
+
+fi
+
+ac_fn_c_check_decl "$LINENO" "mpz_powm" "ac_cv_have_decl_mpz_powm" "
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+
"
if test "x$ac_cv_have_decl_mpz_powm" = x""yes; then :
ac_have_decl=1
@@ -3140,7 +3191,13 @@ cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_MPZ_POWM $ac_have_decl
_ACEOF
-ac_fn_c_check_decl "$LINENO" "mpz_powm_sec" "ac_cv_have_decl_mpz_powm_sec" "#include <gmp.h>
+ac_fn_c_check_decl "$LINENO" "mpz_powm_sec" "ac_cv_have_decl_mpz_powm_sec" "
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+
"
if test "x$ac_cv_have_decl_mpz_powm_sec" = x""yes; then :
ac_have_decl=1
diff --git a/configure.ac b/configure.ac
index a03a72f..2b68d71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,9 +10,22 @@ AC_CONFIG_HEADERS([src/config.h])
AC_PROG_CC
# Checks for libraries.
-AC_CHECK_LIB
-AC_CHECK_DECLS([mpz_powm], [], [], [[#include <gmp.h>]])
-AC_CHECK_DECLS([mpz_powm_sec], [], [], [[#include <gmp.h>]])
+AC_CHECK_LIB([gmp], [__gmpz_init])
+AC_CHECK_LIB([mpir], [__gmpz_init])
+AC_CHECK_DECLS([mpz_powm], [], [], [
+[#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+]])
+AC_CHECK_DECLS([mpz_powm_sec], [], [], [
+[#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+]])
# Checks for header files.
AC_CHECK_HEADERS([inttypes.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h])
diff --git a/setup.py b/setup.py
index 3a8abfc..09fbc09 100644
--- a/setup.py
+++ b/setup.py
@@ -37,11 +37,12 @@
__revision__ = "$Id$"
from distutils import core
+from distutils.ccompiler import new_compiler
from distutils.core import Extension, Command
from distutils.command.build import build
from distutils.command.build_ext import build_ext
-import os, sys
+import os, sys, re
import struct
if sys.version[0:1] == '1':
@@ -190,26 +191,32 @@ class PCTBuildExt (build_ext):
build_ext.build_extensions(self)
def detect_modules (self):
- # Add special include directory for MSVC (because MSVC is special)
+ # Read the config.h file (usually generated by autoconf)
if self.compiler.compiler_type == 'msvc':
+ # Add special include directory for MSVC (because MSVC is special)
self.compiler.include_dirs.insert(0, "src/inc-msvc/")
+ ac = self.__read_autoconf("src/inc-msvc/config.h")
+ else:
+ ac = self.__read_autoconf("src/config.h")
# Detect libgmp or libmpir and don't build _fastmath if both are missing.
- lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib', '/usr/local/lib']
- if not (self.compiler.find_library_file(lib_dirs, 'gmp') or
- self.compiler.find_library_file(lib_dirs, 'mpir')):
- PrintErr ("warning: GMP or MPIR library not found; Not building "+
- "Crypto.PublicKey._fastmath.")
- self.__remove_extensions(["Crypto.PublicKey._fastmath"])
- # Change library to libmpir if libgmp is missing
- elif not (self.compiler.find_library_file(lib_dirs, 'gmp')):
+ if ac.get("HAVE_LIBGMP"):
+ # Default; no changes needed
+ pass
+ elif ac.get("HAVE_LIBMPIR"):
+ # Change library to libmpir if libgmp is missing
self.__change_extension_lib(["Crypto.PublicKey._fastmath"],
['mpir'])
- # And if this is Windows, we need to add a linker option
+ # And if this is MSVC, we need to add a linker option
# to make a static libmpir link well into a dynamic _fastmath
- if sys.platform == 'win32':
+ if self.compiler.compiler_type == 'msvc':
self.__add_extension_link_option(["Crypto.PublicKey._fastmath"],
["/NODEFAULTLIB:LIBCMT"])
+ else:
+ # No MP library; use _slowmath.
+ PrintErr ("warning: GMP or MPIR library not found; Not building "+
+ "Crypto.PublicKey._fastmath.")
+ self.__remove_extensions(["Crypto.PublicKey._fastmath"])
def __add_extension_link_option(self, names, options):
"""Add linker options for the specified extension(s)"""
@@ -257,9 +264,33 @@ class PCTBuildExt (build_ext):
if compiler is not None:
compiler.append(option)
+ def __read_autoconf(self, filename):
+ rx_define = re.compile(r"""^#define (\S+) (?:(\d+)|(".*"))$""")
+
+ result = {}
+ f = open(filename, "r")
+ try:
+ config_lines = f.read().replace("\r\n", "\n").split("\n")
+ for line in config_lines:
+ m = rx_define.search(line)
+ if not m: continue
+ sym = m.group(1)
+ n = m.group(2)
+ s = m.group(3)
+ if n:
+ result[sym] = int(n)
+ elif s:
+ result[sym] = eval(s) # XXX - hack to unescape C-style string
+ else:
+ continue
+ finally:
+ f.close()
+ return result
+
class PCTBuild(build):
def has_configure(self):
- return sys.platform != 'win32'
+ compiler = new_compiler(compiler=self.compiler)
+ return compiler.compiler_type != 'msvc'
sub_commands = [ ('build_configure', has_configure) ] + build.sub_commands
@@ -276,10 +307,9 @@ class PCTBuildConfigure(Command):
if not os.path.exists("config.status"):
if os.system("chmod 0755 configure") != 0:
raise RuntimeError("chmod error")
+ cmd = "sh configure" # we use "sh" here so that it'll work on mingw32 with standard python.org binaries
if self.verbose < 1:
- cmd = "./configure -q"
- else:
- cmd = "./configure"
+ cmd += " -q"
if os.system(cmd) != 0:
raise RuntimeError("autoconf error")
diff --git a/src/_fastmath.c b/src/_fastmath.c
index f8e6f6a..eff3e29 100644
--- a/src/_fastmath.c
+++ b/src/_fastmath.c
@@ -31,15 +31,21 @@
#include "Python.h"
#include "pycrypto_compat.h"
#include <longintrepr.h> /* for conversions */
-#include <gmp.h>
#include "config.h"
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#else
+# error "Neither HAVE_LIBGMP nor HAVE_LIBMPIR are set. Can't build."
+#endif
/* If available, use mpz_powm_sec to avoid timing attacks.
* See the talk by Geremy Condra -
* "PyCon 2011: Through the Side Channel: Timing and Implementation Attacks in Python"
* http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-through-the-side-channel-timing-and-implementation-attacks-in-python-4897955
*/
-#if HAVE_DECL_MPZ_POWM_SEC == 1
+#if HAVE_DECL_MPZ_POWM_SEC
#define MPZ_POWM mpz_powm_sec
#else
#define MPZ_POWM mpz_powm
diff --git a/src/config.h.in b/src/config.h.in
index b71dd4e..514c060 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -11,8 +11,11 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if you have the `' library (-l). */
-#undef HAVE_LIB
+/* Define to 1 if you have the `gmp' library (-lgmp). */
+#undef HAVE_LIBGMP
+
+/* Define to 1 if you have the `mpir' library (-lmpir). */
+#undef HAVE_LIBMPIR
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
diff --git a/src/inc-msvc/config.h b/src/inc-msvc/config.h
index 19ced1d..aa42a7b 100644
--- a/src/inc-msvc/config.h
+++ b/src/inc-msvc/config.h
@@ -1,3 +1,13 @@
+/* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you
+ don't. */
+#undef HAVE_DECL_MPZ_POWM
+
/* Define to 1 if you have the declaration of `mpz_powm_sec', and to 0 if you
don't. */
-#define HAVE_DECL_MPZ_POWM_SEC 0
+#undef HAVE_DECL_MPZ_POWM_SEC
+
+/* Define to 1 if you have the `gmp' library (-lgmp). */
+#undef HAVE_LIBGMP
+
+/* Define to 1 if you have the `mpir' library (-lmpir). */
+#undef HAVE_LIBMPIR