l...@gnu.org (Ludovic Courtès) writes: > Reviving the discussion, as we’ve been discussing this at the GHM, and > some people would really like to see it happen. :-)
Great! Any summary of the discussion, for those of us who couldn't make it there? > ni...@lysator.liu.se (Niels Möller) skribis: > >> To try that out, I'm working with a slightly patched guile: > > Do you still have the patch around? I'm attaching a patch from I tree I have around, without reading it carefully. I'm not sure this is the latest version I worked with. Maybe it's of some use. >> 1. The header file libguile.h. As far as I understand, this is a public >> header file and it's use of <gmp.h> means that the public guile ABI >> depends on gmp. > > The problem is that there’s a public API dealing with mpz_t: Exactly. To me, that seems like a potentially hairy problem to get right. > SCM_API void scm_to_mpz (SCM x, mpz_t rop); > SCM_API SCM scm_from_mpz (mpz_t rop); > > So, when mini-gmp is used, a <gmp.h> header should be installed as well, > say under <libguile/mini-gmp.h>. WDYT? Maybe it would make sense with a level of indirection. User's could include libguile/bignum.h, which would in turn include either mini-gmp.h or the real gmp.h, depending on how guile was configured. Users may also need some way of figuring out if they need to link with -lgmp or not. >> Since mini-gmp is not binary compatible, > > I don’t think there’s a problem, because only mpz_t objects appear in > the API, and they’re pointers. mpz_t is a typedef, which is a single element array of a semi-internal struct. So when you declare mpz_t x; you are really declaring a struct, not a pointer (and then the array type automatically "decays" to a pointer when passed as a function argument). But it's likely that mini-gmp will use the same size of that struct. And even the same layout. I think the main ABI incompatibilities are that 1. symbol names, as seen by the linker, are different. With gmp, mpz_foo is a name mangling #define, and the real name is ___gmpz_foo. mini-gmp doesn't do that. 2. mp_limb_t may be of different size: With mini-gmp, it's always unsigned long, with gmp it's unsigned long long on some platforms (notably 64-bit windows, I think). Hmm, or if you're saying that the use of mpz_t in guile's public API is pointers only, that that might make things a little simpler. But things will still break badly if the user's code is linked with gmp and guile uses mini-gmp, or vice versa. >> 4. mini-gmp has no mp_set_memory_functions. That's added now, with the subtle difference that mini-gmp doesn't pass a valid size for the old_size argument for the free and realloc functions. I don't think guile depends on that feature. Please also note that the most recent version of mini-gmp is now the one included in the main gmp repo.
diff --git a/configure.ac b/configure.ac index a32ff4b..089dfbe 100644 --- a/configure.ac +++ b/configure.ac @@ -146,6 +146,10 @@ AC_ARG_ENABLE(regex, [ --disable-regex omit regular expression interfaces],, enable_regex=yes) +AC_ARG_ENABLE(gmp, + [ --disable-gmp omit high performance bignums],, + enable_gmp=yes) + AC_ARG_ENABLE([deprecated], AS_HELP_STRING([--disable-deprecated],[omit deprecated features])) @@ -869,15 +873,20 @@ fi AC_CACHE_SAVE dnl GMP tests +if test "x$enable_gmp" != xno ; then AC_LIB_HAVE_LINKFLAGS([gmp], [], [#include <gmp.h>], [mpz_import (0, 0, 0, 0, 0, 0, 0);]) if test "x$HAVE_LIBGMP" != "xyes"; then - AC_MSG_ERROR([GNU MP 4.1 or greater not found, see README]) + AC_MSG_NOTICE([GNU MP 4.1 or greater not found, see README]) + enable_gmp=no +fi +fi +if test "x$enable_gmp" = xno ; then + AC_LIBOBJ([mini-gmp]) fi - dnl GNU libunistring is checked for by Gnulib's `libunistring' module. if test "x$LTLIBUNISTRING" = "x"; then AC_MSG_ERROR([GNU libunistring is required, please install it.]) @@ -1253,7 +1262,7 @@ main (int argc, char **argv) # Boehm's GC library # #-------------------------------------------------------------------- -PKG_CHECK_MODULES([BDW_GC], [bdw-gc]) +# PKG_CHECK_MODULES([BDW_GC], [bdw-gc]) save_LIBS="$LIBS" LIBS="$BDW_GC_LIBS $LIBS" diff --git a/libguile.h b/libguile.h index 7ac98a5..457dd66 100644 --- a/libguile.h +++ b/libguile.h @@ -22,8 +22,11 @@ /* This needs to be included outside of the extern "C" block. */ +#if HAVE_LIBGMP #include <gmp.h> - +#else +#include "libguile/mini-gmp.h" +#endif #ifdef __cplusplus extern "C" { #endif diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c index 811e8d8..240e457 100644 --- a/libguile/bytevectors.c +++ b/libguile/bytevectors.c @@ -24,7 +24,11 @@ #include <alloca.h> #include <assert.h> +#if HAVE_LIBGMP #include <gmp.h> +#else +#include "mini-gmp.h" +#endif #include "libguile/_scm.h" #include "libguile/extensions.h" diff --git a/libguile/init.c b/libguile/init.c index 35ab856..bb79422 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -29,7 +29,11 @@ #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> +#if HAVE_LIBGMP #include <gmp.h> +#else +#include "mini-gmp.h" +#endif #include "libguile/_scm.h" diff --git a/libguile/numbers.h b/libguile/numbers.h index b7bcfe4..166f222 100644 --- a/libguile/numbers.h +++ b/libguile/numbers.h @@ -22,9 +22,11 @@ */ - +#ifdef HAVE_LIBGMP #include <gmp.h> - +#else +#include "mini-gmp.h" +#endif #include "libguile/__scm.h" #include "libguile/print.h" diff --git a/libguile/random.c b/libguile/random.c index 8bc0d87..c216245 100644 --- a/libguile/random.c +++ b/libguile/random.c @@ -25,7 +25,11 @@ #include "libguile/_scm.h" +#if HAVE_LIBGMP #include <gmp.h> +#else +#include "mini-gmp.h" +#endif #include <stdio.h> #include <math.h> #include <string.h> diff --git a/libguile/socket.c b/libguile/socket.c index d085d33..5ec20a2 100644 --- a/libguile/socket.c +++ b/libguile/socket.c @@ -25,7 +25,11 @@ #endif #include <errno.h> +#if HAVE_LIBGMP #include <gmp.h> +#else +#include "mini-gmp.h" +#endif #include "libguile/_scm.h" #include "libguile/arrays.h"
Regards, /Niels -- Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26. Internet email is subject to wholesale government surveillance.