diff options
author | Dwayne C. Litzenberger <dlitz@dlitz.net> | 2011-10-10 19:14:30 -0400 |
---|---|---|
committer | Dwayne C. Litzenberger <dlitz@dlitz.net> | 2011-10-10 19:15:50 -0400 |
commit | 323ce9ef951378dc96ce14c9e514e9aa19ab39d9 (patch) | |
tree | 5986ee1d95f37cdb4605b5b4899667747ae40dfc | |
parent | 32114297da2450af00c4612596bc15da4f6256f2 (diff) | |
download | pycrypto-323ce9ef951378dc96ce14c9e514e9aa19ab39d9.tar.gz |
Fix libgmp/libmpir autodetection
-rwxr-xr-x | configure | 87 | ||||
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | setup.py | 62 | ||||
-rw-r--r-- | src/_fastmath.c | 10 | ||||
-rw-r--r-- | src/config.h.in | 7 | ||||
-rw-r--r-- | src/inc-msvc/config.h | 12 |
6 files changed, 158 insertions, 39 deletions
@@ -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]) @@ -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 |