dnl Process this file with autoconf to produce a configure script.

AC_INIT(avram,0.13.0,ursala-users@freelists.org)
dnl Every other copy of the package version number gets its value from here
AM_INIT_AUTOMAKE(avram, 0.13.0)
AM_CONFIG_HEADER(config.h)
AC_SUBST(VERSION)

ISODATE=`date +%Y-%m-%d`
AC_SUBST(ISODATE)

dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_CC
AC_PROG_MAKE_SET
AM_PROG_CC_C_O

dnl Checks for header files.

AC_HEADER_STDC

AC_CHECK_HEADERS(
   ctype.h fcntl.h strings.h time.h sys/file.h sys/time.h unistd.h math.h,,
   [AC_MSG_ERROR(missing one of ctype.h fcntl.h strings.h time.h sys/file.h sys/time.h unistd.h math.h)])

AC_CHECK_HEADER(
   argz.h,
   [AC_DEFINE([HAVE_ARGZ_H],1,[if you have the argz library])],
   [AC_MSG_WARN(no argz.h so AVMINPUTS unsupported)])

AC_CHECK_HEADER(
   fenv.h,
   [AC_DEFINE([HAVE_FENV],1,[if you have floating point math])],
   [AC_MSG_WARN(no fenv.h so floating math unsupported)])

AC_CHECK_HEADER(
   complex.h,
   [AC_DEFINE([HAVE_COMPLEX],1,[if you have complex math])],
   [AC_MSG_WARN(no complex.h so complex math unsupported)])

AC_CHECK_HEADER(
   setjmp.h,
   [AC_DEFINE([HAVE_SETJMP],1,[Define if you have setjmp functions])],
   [AC_MSG_WARN(setjmp not detected for memory management)])

AC_CHECK_HEADER(
   malloc.h,
   [AC_CHECK_DECLS(
      __malloc_hook,
      [AC_CHECK_DECLS(
         __realloc_hook,
         [AC_CHECK_DECLS(
            __free_hook,
            [AC_DEFINE([HAVE_MALLOC],1,[Define if you have the standard malloc.h header])],
            [AC_MSG_WARN(__free_hook not detected for memory management)],
            [#include<malloc.h>])],
         [AC_MSG_WARN(__realloc_hook not detected for memory management)],
         [#include<malloc.h>])],
      [AC_MSG_WARN(__malloc_hook not detected for memory management)],
      [#include<malloc.h>])],
   [AC_MSG_WARN(malloc.h header not detected for memory management)])

dnl Checks for typedefs, structures, and compiler characteristics.

dnl AC_CANONICAL_HOST
AC_C_CONST
AC_TYPE_SIZE_T

dnl Checks for library functions.

AC_CHECK_FUNCS(
  strdup strstr,,
  [AC_MSG_ERROR(missing either strdup or strstr)])

AC_CHECK_FUNCS(ctime_r,,[AC_MSG_WARN(no ctime_r so using non-reentrant ctime)])
AC_CHECK_FUNCS(strerror,,[AC_MSG_WARN(no strerror so error messages truncated)])
AC_REPLACE_FUNCS(memmove)

dnl checks for libraries

AM_PATH_LIBGCRYPT(
    ,
    [AC_DEFINE([HAVE_GCRYPT],1,[Define if you have libgcrypt]) LIBS="$LIBGCRYPT_LIBS $LIBS"],
    [AC_MSG_WARN(no gcrypt so remote execution disabled)])

dnl allow for a non-root installation
LDFLAGS="$LDFLAGS -L$HOME/lib"
CPPFLAGS="$CPPFLAGS -I$HOME/include"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib $LIBLTDL"
dnl LDFLAGS="$LDFLAGS -L$HOME/lib $LIBLTDL"
dnl CPPFLAGS="$CPPFLAGS -I$HOME/include $LTDLINCL"

dnl is there a macro to check for a list of headers atomically?

AC_CHECK_LIB(
   gslcblas,
   cblas_xerbla,
   LIBS="-lgslcblas "$LIBS; [AC_CHECK_LIB(
      gsl,
      gsl_sf_bessel_J0,
      [AC_CHECK_HEADER(
         gsl/gsl_deriv.h,
         [AC_CHECK_HEADER(
            gsl/gsl_sum.h,
            [AC_CHECK_HEADER(
               gsl/gsl_integration.h,
               [AC_CHECK_HEADER(
                  gsl/gsl_math.h,
                  [AC_CHECK_HEADER(
                     gsl/gsl_sf_bessel.h,
                     [AC_CHECK_HEADER(
                        gsl/gsl_errno.h,
                        [AC_DEFINE([HAVE_GSL],1,[Define if you have the GNU Scientific library]) LIBS="-lgsl "$LIBS],
                        [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
                     [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
                  [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
               [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
            [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
         [AC_MSG_WARN(no gsl headers so numerical analysis functions disabled)])],
      [])],
   [AC_MSG_WARN(no gsl cblas library so numerical functions disabled)],
   [])

AC_CHECK_LIB(
   glpk,
   glp_create_index,
   [AC_CHECK_HEADER(
      glpk.h,
      [AC_DEFINE([HAVE_GLPK],1,[Define if you have the GNU linear programming kit]) LIBS="-lglpk "$LIBS],
      [AC_MSG_WARN(no glpk.h so linear programming functions disabled)])],
   [AC_MSG_WARN(no glpk lib so linear programming disabled)])

AC_CHECK_LIB(
   colamd,
   symamd,
   LIBS="-lcolamd "$LIBS; [AC_CHECK_LIB(
      lpsolve55,
      make_lp,
      [AC_CHECK_HEADER(
         lpsolve/lp_lib.h,
         [AC_DEFINE([HAVE_LPSOLVE],1,[Define if you have lpsolve]) LIBS="-llpsolve55 "$LIBS],
         [AC_MSG_WARN(no lp_lib.h so linear programming functions disabled)])],
      [AC_MSG_WARN(no lpsolve55 lib so linear programming disabled)])],
   [AC_MSG_WARN(no libltdl so lpsolve disabled)])

AC_CHECK_LIB(
   mpfr,
   mpfr_add,
   [AC_CHECK_HEADER(
      mpfr.h,
      AC_DEFINE([HAVE_MPFR],1,[Define if you have the mpfr arbitrary precision library]) LIBS="-lmpfr "$LIBS,
      [AC_MSG_WARN(no mpfr.h header so arbitrary precision math disabled)])],
   [AC_MSG_WARN(no mpfr library so arbitrary precision math disabled)])

dnl the gmp header file isn't needed

AC_CHECK_LIB(
   gmp,
   __gmp_randinit_default,
   [AC_DEFINE([HAVE_GMP],1,[Define if you have GNU multiple precision library]) LIBS="-lgmp "$LIBS],
   [AC_MSG_WARN(no libgmp so arbitrary precision math partly disabled)])

dnl umfpak requires blas and amd libraries already defined or else the check for it won't work

AC_CHECK_LIB(
   blas,
   dscal_,
   [AC_CHECK_LIB(
      amd,
      amd_free,
      LIBS="-lblas -lamd "$LIBS; [AC_CHECK_LIB(
         umfpack,
         umfpack_di_free_numeric,
         [AC_CHECK_HEADER(
            suitesparse/umfpack.h,
            [AC_DEFINE([HAVE_UMF],1,[Define if you have the ufsparse libraries]) LIBS="-lumfpack "$LIBS],
            [AC_MSG_WARN(no umfpack.h header so sparse matrices disabled)])],
         [AC_MSG_WARN(no umfpack library so sparse matrices disabled)],
         [])],
      [AC_MSG_WARN(no amd library so sparse matrices disabled)],
      [])],
   [AC_MSG_WARN(no blas so sparse matrices disabled)],
   [])

dnl lapack has no header file so only the library is checked
dnl harminv is checked only if lapack is present

AC_CHECK_LIB(
   lapack,
   dgesvx_,
   [AC_DEFINE([HAVE_LAPACK],1,[Define if you have the lapack library]) LIBS="-llapack "$LIBS; AC_CHECK_LIB(
      harminv,
      harminv_solve,
      AC_DEFINE([HAVE_HARMINV],1,[Define if you have the harminv library]) LIBS="-lharminv  "$LIBS,
      [AC_MSG_WARN(no harminv library so harmonic inversiondisabled)],
      [])],
   [AC_MSG_WARN(no lapack so some linear algebra functions disabled)],
   [])

AC_CHECK_LIB(
   fftw3,
   fftw_plan_dft_1d,
   [AC_CHECK_HEADER(
      fftw3.h,
      [AC_DEFINE([HAVE_FFTW],1,[Define if you have the fftw library]) LIBS=$LIBS" -lfftw3"],
      [AC_MSG_WARN(no fftw.h header so fourier transforms disabled)])],
   [AC_MSG_WARN(no fftw library so fourier transforms disabled)],
   [])

dnl minpack.h might be a Debian addition

AC_CHECK_LIB(
   minpack,
   hybrd_,
   [AC_CHECK_HEADER(
      minpack.h,
      [AC_DEFINE([HAVE_MINPACK],1,[Define if you have the minpack library]) LIBS="-lminpack "$LIBS],
      [AC_MSG_WARN(no minpack.h header so non-linear optimization disabled)])],
   [AC_MSG_WARN(no minpack library so non-linear optimization disabled)],
   [])

AC_CHECK_LIB(
   sundials_kinsol,
   KINCreate,
   [AC_CHECK_LIB(
      sundials_nvecserial,
      N_VNew_Serial,
      CPPFLAGS="$CPPFLAGS -I/usr/include/sundials -I/usr/include/kinsol -I/usr/include/nvector"; [AC_CHECK_HEADER(
         sundials_types.h,
         [AC_CHECK_HEADER(
            sundials_math.h,
            [AC_CHECK_HEADER(
               sundials_nvector.h,
dnl            [AC_CHECK_HEADER(
dnl               sundials_smalldense.h,
                  [AC_CHECK_HEADER(
                     kinsol.h,
                     [AC_CHECK_HEADER(
                        kinsol_dense.h,
                        [AC_CHECK_HEADER(
                           kinsol_spgmr.h,
                           [AC_CHECK_HEADER(
                              kinsol_spbcgs.h,
                              [AC_CHECK_HEADER(
                                 kinsol_sptfqmr.h,
                                 [AC_CHECK_HEADER(
                                    kinsol_spils.h,
                                    [AC_CHECK_HEADER(
                                       nvector_serial.h,
                                       [AC_DEFINE(
                                          [HAVE_KINSOL],
                                          1,
                                          [Define for sundials]) LIBS="-lsundials_kinsol -lsundials_nvecserial "$LIBS],
                                       [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                                    [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                                 [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                              [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                           [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                        [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
                     [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
dnl               [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
               [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
            [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
         [AC_MSG_WARN(no kinsol headers so non-linear optimization disabled)])],
      [AC_MSG_WARN(no kinsol library so non-linear optimization disabled)],
      [])],
   [AC_MSG_WARN(no kinsol library so non-linear optimization disabled)],
   [])


dnl checking for the Rmath header requires MATHLIB_STANDALONE to be defined or it won't work

AC_CHECK_LIB(
   Rmath,
   bessel_i,
   CPPFLAGS="$CPPFLAGS -DMATHLIB_STANDALONE"; [AC_CHECK_HEADER(
      Rmath.h,
      [AC_DEFINE([HAVE_RMATH],1,[Define if you have the GNU R math library]) LIBS="-lRmath -lm "$LIBS],   
      [AC_MSG_WARN(no Rmath.h header so statistical functions disabled)])],
   [AC_MSG_WARN(no Rmath library so statistical functions disabled)],
   [])

dnl is there a right way to detect and link a shared library whose filename ends with .so.something?

AC_CHECK_FILE(
   /usr/lib/libexpect.so.5,
   EXPATH=" /usr/lib/libexpect.so.5",
   [AC_CHECK_FILE(
      /usr/local/lib/libexpect.so.5,
      EXPATH=" /usr/local/lib/libexpect.so.5",
      [AC_CHECK_FILE(
         $HOME/lib/libexpect.so.5,
         EXPATH=" $HOME/lib/libexpect.so.5",
         [AC_CHECK_FILE(
            /lib/libexpect.so.5,
            EXPATH=" /lib/libexpect.so.5",
            [AC_CHECK_FILE(
               /usr/lib/libexpect.so,
               EXPATH=" /usr/lib/libexpect.so",
               [AC_CHECK_FILE(
                  /usr/local/lib/libexpect.so,
                  EXPATH=" /usr/local/lib/libexpect.so",
                  [AC_CHECK_FILE(
                     $HOME/lib/libexpect.so,
                     EXPATH=" $HOME/lib/libexpect.so",
                     [AC_CHECK_FILE(
                        /lib/libexpect.so,
                        EXPATH=" /lib/libexpect.so",
                        [AC_CHECK_FILE(
                           /usr/lib/libexpect5.43.so,
                           EXPATH=" /usr/lib/libexpect5.43.so",
                           [AC_CHECK_FILE(
                              /usr/local/lib/libexpect5.43.so,
                              EXPATH=" /usr/local/lib/libexpect5.43.so",
                              [AC_CHECK_FILE(
                                 $HOME/lib/libexpect5.43.so,
                                 EXPATH=" $HOME/lib/libexpect5.43.so",
                                 [AC_CHECK_FILE(
                                    /lib/libexpect5.43.so,
                                    EXPATH=" /lib/libexpect5.43.so",
                                    [AC_CHECK_FILE(
                                       /lib/libexpect5.44.so,
                                       EXPATH=" /lib/libexpect5.44.so",
                                       [])])])])])])])])])])])])])

AC_CHECK_LIB(
   util,
   openpty,
   [AC_CHECK_HEADER(
      tcl8.4/expect.h,
      AC_DEFINE([HAVE_EXPECT],1,[Define if you have libexpect]) LIBS="-lutil -ltcl8.4"$EXPATH" "$LIBS,
      [AC_CHECK_LIB(
         util,
         openpty,
         [AC_CHECK_HEADER(
            tcl8.5/expect.h,
            AC_DEFINE([HAVE_EXPECT],1,[Define if you have libexpect]) LIBS="-lutil -ltcl8.5"$EXPATH" "$LIBS,
            [AC_MSG_WARN(no libexpect so --interactive is disabled)])],
         [AC_MSG_WARN(no openpty in libutil so --interactive is disabled)])])],
   [AC_MSG_WARN(no openpty in libutil so --interactive is disabled)])

dnl CPPFLAGS="$CPPFLAGS -pedantic -Wall"

CFLAGS="-O3 -mtune=native -march=native"

AC_OUTPUT(Makefile avram.lsm avram.spec avm/Makefile src/Makefile doc/Makefile)
