Rework detection and handling of ndbm: we now check for a working
authorPeter Maydell <pmaydell@chiark.greenend.org.uk>
Sat, 24 Dec 2005 17:17:38 +0000 (17:17 +0000)
committerPeter Maydell <pmaydell@chiark.greenend.org.uk>
Sat, 24 Dec 2005 17:17:38 +0000 (17:17 +0000)
(library,header) combination, and configure defines variables for each
which the makefile and C file just use, rather than a bunch of HAVE_foo
switches. As a bonus, we no longer unnecessarily link every binary with
the ndbm library even though only slocal uses it. Also you can now tell
configure where to get the header/library so even if we guess wrong you
can overrule us.

ChangeLog
INSTALL
acconfig.h
aclocal.m4
configure.in
uip/Makefile.in
uip/slocal.c

index 2a7493f..f81e98e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-12-24  Peter Maydell  <pmaydell@chiark.greenend.org.uk>
+
+       * Completely redo db library checking -- we now check for working
+       (include file, library) pairs rather than checking for headers and
+       libraries separately. We also now provide --with-ndbm=lib and
+       --with-ndbmheader=header options to configure to handle situations
+       where configure's autodetection fails.
+
 2005-12-21  Peter Maydell  <pmaydell@chiark.greenend.org.uk>
 
        * Fix stupid accidental dependence on a bash quirk in previous
 2005-12-21  Peter Maydell  <pmaydell@chiark.greenend.org.uk>
 
        * Fix stupid accidental dependence on a bash quirk in previous
diff --git a/INSTALL b/INSTALL
index c1a91f0..37a38e5 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -246,6 +246,17 @@ Options for configure
      If you wish to use a transport agent other than sendmail, you will
      need to use a `sendmail wrapper'.
 
      If you wish to use a transport agent other than sendmail, you will
      need to use a `sendmail wrapper'.
 
+--with-ndbm=LIB    (DEFAULT is to autodetect)
+--with-ndbmheader=HEADER     (DEFAULT is to autodetect)
+     Specify the header file (eg ndbm.h) and library (eg ndbm) to use
+     to compile against the ndbm database library. By default, configure
+     will try various possibilities until it finds one that works; this
+     option only needs to be specified if the autodetection fails or
+     makes the wrong choice.
+
+     If either of these options is given then the other must also be
+     specified.
+
 --with-pager=PAGER    (DEFAULT is more)
      Specify the default pager (file lister) to use.  If this option
      is not given, then the configuration process will search for the
 --with-pager=PAGER    (DEFAULT is more)
      Specify the default pager (file lister) to use.  If this option
      is not given, then the configuration process will search for the
index cedaa55..551b253 100644 (file)
 /* Define if your system has netdb.h */
 #undef HAVE_NETDB_H
 
 /* Define if your system has netdb.h */
 #undef HAVE_NETDB_H
 
-/* Define if your system has db1/ndbm.h instead of ndbm.h (ppclinux) */
-#undef HAVE_DB1_NDBM_H
-
 /* Define to the header containing the declaration of initgroups() on your
    system, if any.  AIX 4.[13], SunOS 4.1.3, and ULTRIX 4.2A have the function
    in libc but don't have a declaration anywhere. */
 #undef INITGROUPS_HEADER
 
 /* Define to the header containing the declaration of initgroups() on your
    system, if any.  AIX 4.[13], SunOS 4.1.3, and ULTRIX 4.2A have the function
    in libc but don't have a declaration anywhere. */
 #undef INITGROUPS_HEADER
 
+/* Define to the header containing the ndbm API prototypes */
+#undef NDBM_HEADER
+
 /* Define if your system actually has a prototype for snprintf() in <stdio.h>
    (or a file it includes) rather than just having a "stealth" definition of it
    in libc.a the way AIX 4.1 does. */
 /* Define if your system actually has a prototype for snprintf() in <stdio.h>
    (or a file it includes) rather than just having a "stealth" definition of it
    in libc.a the way AIX 4.1 does. */
index 421386e..c0d4fb8 100644 (file)
@@ -24,16 +24,19 @@ dnl --------------
 dnl CHECK FOR NDBM
 dnl --------------
 dnl
 dnl CHECK FOR NDBM
 dnl --------------
 dnl
-dnl NMH_CHECK_DBM(libname,action-if-true,action-if-false,other-libraries)
+dnl NMH_CHECK_DBM(include,library,action-if-found,action-if-not)
+
 dnl Check for presence of dbm_open() in the specified library
 dnl Check for presence of dbm_open() in the specified library
-dnl (if libname is the empty string then don't try to link against
-dnl any particular library). If action-if-true is unspecified it
-dnl defaults to adding "-llibname" to the beginning of LIBS.
-dnl If other-libraries is specified then these are prepended to
-dnl LIBS for the duration of the check.
-dnl NB that the checks for the right dbm header files must
-dnl be done before using this macro!
-dnl
+dnl and with the specified include file (if libname is the empty
+dnl string then don't try to link against any particular library).
+
+dnl We set nmh_ndbm_found to 'yes' or 'no'; if found we set
+dnl nmh_ndbmheader to the first arg and nmh_ndbm to the second.
+
+dnl If this macro accepted a list of include,library tuples
+dnl to test in order that would be cleaner than the current
+dnl nest of calls in configure.in.
+
 dnl We try to link our own code fragment (which includes the
 dnl headers in the same way slocal.c does) rather than
 dnl using AC_CHECK_LIB because on later versions of libdb
 dnl We try to link our own code fragment (which includes the
 dnl headers in the same way slocal.c does) rather than
 dnl using AC_CHECK_LIB because on later versions of libdb
@@ -42,45 +45,42 @@ dnl we don't want to hardcode searching for the internal
 dnl function that lies behind it. (AC_CHECK_LIB works by
 dnl defining its own bogus prototype rather than pulling in
 dnl the right header files.)
 dnl function that lies behind it. (AC_CHECK_LIB works by
 dnl defining its own bogus prototype rather than pulling in
 dnl the right header files.)
-AC_DEFUN(NMH_CHECK_DBM,
+
+dnl An oddity (bug) of this macro is that if you haven't
+dnl done AC_PROG_CC or something that implies it before
+dnl using this macro autoconf complains about a recursive
+dnl expansion.
+
+AC_DEFUN(NMH_CHECK_NDBM,
 [
 [
-if test "x$1" = "x"; then
-   nmh_libs=
-   dnl this is just for the benefit of AC_CACHE_CHECK's message
-   nmh_testname=libc
+if test "x$2" = "x"; then
+  nmh_libs=
+  AC_MSG_CHECKING([for dbm in $1])
 else
 else
-   nmh_libs="-l$1 "
-   nmh_testname="$1"
+  nmh_libs="-l$2 "
+  AC_MSG_CHECKING([for dbm in $1 and $2])
 fi
 fi
-AC_CACHE_CHECK([for dbm in $nmh_testname], [nmh_cv_check_dbm_$1],[
+
+dnl We don't try to cache the result, because that exceeds
+dnl my autoconf skills -- feel free to put it in :-> -- PMM
+
 nmh_saved_libs="$LIBS"
 nmh_saved_libs="$LIBS"
-LIBS="$nmh_libs $4 $LIBS"
+LIBS="$nmh_libs $5 $LIBS"
 AC_LINK_IFELSE(AC_LANG_PROGRAM([[
 AC_LINK_IFELSE(AC_LANG_PROGRAM([[
-#ifdef HAVE_DB1_NDBM_H
-#include <db1/ndbm.h>
-#else
-#ifdef HAVE_GDBM_NDBM_H
-#include <gdbm/ndbm.h>
-#else
-#if defined(HAVE_DB_H)
 #define DB_DBM_HSEARCH 1
 #define DB_DBM_HSEARCH 1
-#include <db.h>
-#else
-#include <ndbm.h>
-#endif
-#endif
-#endif
+#include <$1>
 ]],
 ]],
-[[dbm_open("",0,0);]]),[nmh_cv_check_dbm_$1=yes],[
-nmh_cv_check_dbm_$1=no])
+[[dbm_open("",0,0);]]),[nmh_ndbm_found=yes],[nmh_ndbm_found=no])
 LIBS="$nmh_saved_libs"
 LIBS="$nmh_saved_libs"
-])
-if eval "test \"`echo '$nmh_cv_check_dbm_'$1`\" = yes"; then
-  nmh_tr_macro=HAVE_LIB`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  AC_DEFINE_UNQUOTED($nmh_tr_macro)
-  m4_if([$2],,[LIBS="$nmh_libs$LIBS"],[$2])
-else
+
+if test "$nmh_ndbm_found" = "yes"; then
+  AC_MSG_RESULT(yes)
+  nmh_ndbmheader="$1"
+  nmh_ndbm="$2"
   $3
   $3
+else
+  AC_MSG_RESULT(no)
+  $4
   :
 fi
 ])dnl
   :
 fi
 ])dnl
index 1ff16b2..2485a5f 100644 (file)
@@ -599,36 +599,68 @@ if test "x$ac_found_iconv" = "xyes"; then
     [Define as const if the declaration of iconv() needs const.])
 fi
 
     [Define as const if the declaration of iconv() needs const.])
 fi
 
-dnl ----------------
-dnl CHECK FOR NDBM.H
-dnl ----------------
-
-AC_CHECK_HEADERS(db1/ndbm.h gdbm/ndbm.h db.h, break, )
-
 dnl --------------
 dnl CHECK FOR NDBM
 dnl --------------
 dnl --------------
 dnl CHECK FOR NDBM
 dnl --------------
-dnl Checks for ndbm; we use our own autoconf macro rather than
-dnl using AC_CHECK_LIB because on later versions of libdb
-dnl the dbm_open() function is provided via a #define and
-dnl we don't want to hardcode searching for the internal
-dnl function that lies behind it.
-dnl This *must* come after the ndbm headers check!
-
-dnl Note the special-casing of the gdbm_compat case:
-dnl if we find gdbm_open in -lgdbm and dbm_open in
-dnl -lgdbm_compat -lgdbm then we want to have both libraries
-dnl in LIBS in that order.
-NMH_CHECK_DBM(,,
-  NMH_CHECK_DBM(ndbm,,
-    NMH_CHECK_DBM(dbm,,
-      NMH_CHECK_DBM(db1,,
-        NMH_CHECK_DBM(db,,
-          NMH_CHECK_DBM(gdbm,,
-            AC_CHECK_LIB(gdbm,gdbm_open,
-              NMH_CHECK_DBM(gdbm_compat,LIBS="-lgdbm_compat -lgdbm $LIBS",
-                 AC_MSG_ERROR([cannot find a library providing dbm_open()]),-lgdbm),
-              AC_MSG_ERROR([cannot find a library providing dbm_open()]))))))))
+
+AC_ARG_WITH([ndbm],AS_HELP_STRING([--with-ndbm=ARG],[use -lARG to link with ndbm]),
+            [nmh_ndbm=$withval],[nmh_ndbm=autodetect])
+AC_ARG_WITH([ndbmheader],AS_HELP_STRING([--with-ndbmheader=ARG],[#include <ARG> to use ndbm]),
+            [nmh_ndbmheader=$withval],[nmh_ndbmheader=autodetect])
+
+if test "$nmh_ndbm" = "autodetect"; then
+  if test "$nmh_ndbmheader" != "autodetect"; then
+    AC_MSG_ERROR([must specify both --with-ndbm and --with-ndbmheader or neither])
+  else
+
+    dnl There are at least four implementations of ndbm, and
+    dnl several of those can be in different places at the whim
+    dnl of the system integrator. A good summary of this mess
+    dnl can be found at http://www.unixpapa.com/incnote/dbm.html
+
+    dnl Classic ndbm with no library required (eg NetBSD): try this
+    dnl first so we don't accidentally link in a pointless but harmless
+    dnl library in one of the later ndbm.h+libfoo tests:
+    NMH_CHECK_NDBM(ndbm.h,,,
+    dnl Berkeley DBv2 emulating ndbm: header in db.h:
+      NMH_CHECK_NDBM(db.h,db,,
+    dnl Berkeley DBv1 emulating ndbm:
+        NMH_CHECK_NDBM(ndbm.h,db,,
+          NMH_CHECK_NDBM(ndbm.h,db1,,
+    dnl Classic ndbm:
+            NMH_CHECK_NDBM(ndbm.h,ndbm,,
+    dnl glibc2.1 systems put db1 in a subdir:
+              NMH_CHECK_NDBM(db1/ndbm.h,db1,,
+    dnl GNU gdbm emulating ndbm, with header possibly in gdbm/
+    dnl and possibly needing gbdm_compat library:
+                NMH_CHECK_NDBM(gdbm/ndbm.h,gdbm,,
+                  NMH_CHECK_NDBM(gdbm/ndbm.h,gdbm_compat -lgdbm,,
+                    NMH_CHECK_NDBM(ndbm.h,gdbm,,
+                      NMH_CHECK_NDBM(ndbm.h,gdbm_compat -lgdbm))))))))))
+
+  fi
+else
+  dnl We don't really need to check that the user-specified values work,
+  dnl but it is a convenience to the user to bomb out early rather than
+  dnl after configure and half the compile process.
+  NMH_CHECK_NDBM([$nmh_ndbmheader],[$nmh_ndbm])
+fi
+
+if test "$nmh_ndbm_found" = "no"; then
+  AC_MSG_ERROR([could not find a working ndbm library/header combination])
+else
+  dnl Now export the lib/header to our makefile/config.h:
+  if test x"$nmh_ndbmheader" != x; then
+    AC_DEFINE_UNQUOTED(NDBM_HEADER, <$nmh_ndbmheader>)
+  fi
+  if test x"$nmh_ndbm" != x; then
+    NDBM_LIBS="-l$nmh_ndbm"
+  else
+    NDBM_LIBS=
+  fi
+  AC_SUBST(NDBM_LIBS)
+fi
+
 
 dnl ----------------
 dnl CHECK FOR HESIOD
 
 dnl ----------------
 dnl CHECK FOR HESIOD
index 54f9634..e58ac4f 100644 (file)
@@ -29,6 +29,7 @@ MTSLIB   = ../mts/libmts.a
 KRB4_LIBS = @KRB4_LIBS@
 SASL_LIBS = @SASL_LIBS@
 HESIOD_LIBS = @HESIOD_LIBS@
 KRB4_LIBS = @KRB4_LIBS@
 SASL_LIBS = @SASL_LIBS@
 HESIOD_LIBS = @HESIOD_LIBS@
+NDBM_LIBS = @NDBM_LIBS@
 LOCALLIBS = ../config/version.o ../config/config.o $(MTSLIB) ../sbr/libmh.a
 LINKLIBS = $(LOCALLIBS) $(KRB4_LIBS) $(SASL_LIBS) $(HESIOD_LIBS) $(LIBS)
 
 LOCALLIBS = ../config/version.o ../config/config.o $(MTSLIB) ../sbr/libmh.a
 LINKLIBS = $(LOCALLIBS) $(KRB4_LIBS) $(SASL_LIBS) $(HESIOD_LIBS) $(LIBS)
 
@@ -228,7 +229,7 @@ show: show.o mhlsbr.o termsbr.o $(LOCALLIBS)
        $(LINK) show.o mhlsbr.o termsbr.o $(LINKLIBS) $(TERMLIB)
 
 slocal: slocal.o aliasbr.o dropsbr.o $(LOCALLIBS)
        $(LINK) show.o mhlsbr.o termsbr.o $(LINKLIBS) $(TERMLIB)
 
 slocal: slocal.o aliasbr.o dropsbr.o $(LOCALLIBS)
-       $(LINK) slocal.o aliasbr.o dropsbr.o $(LINKLIBS)
+       $(LINK) slocal.o aliasbr.o dropsbr.o $(NDBM_LIBS) $(LINKLIBS)
 
 sortm: sortm.o $(LOCALLIBS)
        $(LINK) sortm.o $(LINKLIBS)
 
 sortm: sortm.o $(LOCALLIBS)
        $(LINK) sortm.o $(LINKLIBS)
index 0e77916..993a141 100644 (file)
 extern int  initgroups(char*, int);
 #endif
 
 extern int  initgroups(char*, int);
 #endif
 
-
-#ifdef HAVE_DB1_NDBM_H
-#include <db1/ndbm.h>
-#else
-#ifdef HAVE_GDBM_NDBM_H
-#include <gdbm/ndbm.h>
-#else
-#if defined(HAVE_DB_H)
+/* This define is needed for Berkeley db v2 and above to
+ * make the header file expose the 'historical' ndbm APIs.
+ * We define it unconditionally because this is simple and
+ * harmless.
+ */
 #define DB_DBM_HSEARCH 1
 #define DB_DBM_HSEARCH 1
-#include <db.h>
-#else
-#include <ndbm.h>
-#endif
-#endif
+#ifdef NDBM_HEADER
+#include NDBM_HEADER
 #endif
 
 #include <utmp.h>
 #endif
 
 #include <utmp.h>