AC_PREREQ(2.59)
dnl Process this file with autoconf to produce a configure script.
dnl
dnl aclocal_cache.m4, included by sowing/confdb/aclocal.m4, fixes 
dnl bugs in autoconf caching.
dnl
dnl The file name here refers to a file in the source being configured
AC_INIT(pmiserv.c)
dnl
dnl Definitions will be placed in this file rather than in the DEFS variable
AC_CONFIG_HEADER(pmutilconf.h)
AH_TOP([/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*  
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */
#ifndef FORKERCONF_H_INCLUDED
#define FORKERCONF_H_INCLUDED
])
AH_BOTTOM([#endif])
dnl
dnl Set the directory that contains support scripts such as install-sh and
dnl config.guess
AC_CONFIG_AUX_DIR(../../../confdb)
dnl
echo "RUNNING CONFIGURE FOR THE PM UTILITIES"
dnl
dnl Use AC_ARG_ENABLE to look for --enable-feature and AC_ARG_WITH to look for
dnl --with-capability
dnl
dnl Enable better caching control
PAC_ARG_CACHING
dnl
AC_ARG_ENABLE(echo, 
[--enable-echo  - Turn on strong echoing. The default is enable=no.] ,set -x)
dnl
AC_ARG_ENABLE(strict,[--enable-strict - Turn on strict debugging with gcc],,
enable_strict=no)
dnl
dnl
dnl Set single for now
AC_ARG_ENABLE(g,
[--enable-g=option - Control the level of debugging support in the PMI
implementation.  option may be a list of common separated names including
    none  - No debugging
    all   - All of the above choices],,enable_g=none)
dnl
AC_ARG_ENABLE(onsig,
[--enable-onsig - Control the handling of processes that signal (e.g., SEGV)
 using ptrace.  Disabled by default],,enable_onsig=no)
AC_ARG_ENABLE(newsession,
[--enable-newsession - Create a new process group session if standard in is
                      not connected to a terminal],,enable_newsession=yes)
dnl With options
dnl
dnl First check that we have a clean build if we are doing a VPATH build
PAC_VPATH_CHECK()
dnl
dnl Process any enable or with values
dnl
dnl enable-g
# strip off multiple options, separated by commas
save_IFS="$IFS"
IFS=","
for option in $enable_g ; do
case "$option" in 
    no|none)
    ;;
    mem|dbg|all|yes|debug)
    CFLAGS="$CFLAGS -g"
    ;;
    log|handle|fine-grain-nesting|fg-nesting|nesting)
    # Simply ignore these
    ;;
    *)
    AC_MSG_WARN([Unknown value $option for enable-g])
    ;;
esac
done
IFS="$save_IFS"
dnl
dnl This test is complicated by the fact that top_srcdir is not set until
dnl the very end of configure.  Instead, we get it ourselves
if test -z "$top_srcdir" ; then
   use_top_srcdir=$srcdir   
else
   use_top_srcdir=$top_srcdir
fi

PAC_LOAD_BASE_CACHE

AC_DEFINE(PMUTILCONF_H_INCLUDED,1,[Define so that we can ensure that the config file has been included])
dnl The recommended order for items in a configure.in file is
dnl     check for programs
dnl     check for libraries
dnl     check for header files
dnl     check for typedefs
dnl     check for structures
dnl     check for compiler characteristics
dnl     check for library functions
dnl     check for system services
dnl Here are some sample tests
dnl
dnl Find a C compiler (choose gcc first)
AC_PROG_CC
PAC_PROG_MAKE
AC_CHECK_PROGS(AR,ar)
AC_PROG_RANLIB
# Turn off creating shared libraries for any utility routines
ENABLE_SHLIB=none
AC_SUBST(ENABLE_SHLIB)
dnl
dnl     check for compiler characteristics
dnl Set CFLAGS for enable strict if necessary
PAC_CC_STRICT
AC_C_CONST
PAC_C_VOLATILE
PAC_C_RESTRICT
AC_C_INLINE
PAC_C_GNU_ATTRIBUTE
dnl
dnl check for library functions
AC_CHECK_FUNCS(strtol time gettimeofday)
if test "$enable_onsig" = "yes" ; then
    AC_CHECK_FUNCS(ptrace)
    # It isn't enough to find ptrace.  We also need the ptrace 
    # parameters, which some systems, such as IRIX, do not define.
    if test "$ac_cv_func_ptrace" = yes ; then
        AC_CACHE_CHECK([for ptrace named parameters],
pac_cv_has_ptrace_parms,[
        AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/ptrace.h>],[int i = PTRACE_CONT;],pac_cv_has_ptrace_parms=yes,
pac_cv_has_ptrace_parms=no)])
        if test "$pac_cv_has_ptrace_parms" = "yes" ; then
	    AC_DEFINE(HAVE_PTRACE_CONT,,[Define if ptrace parameters available])
	fi
    fi
fi
# Check for h_addr or h_addr_list
AC_CACHE_CHECK([whether struct hostent contains h_addr_list],
pac_cv_have_haddr_list,[
AC_TRY_COMPILE([
#include <netdb.h>],[struct hostent hp;hp.h_addr_list[0]=0;],
pac_cv_have_haddr_list=yes,pac_cv_have_haddr_list=no)])
if test "$pac_cv_have_haddr_list" = "yes" ; then
    AC_DEFINE(HAVE_H_ADDR_LIST,1,[Define if struct hostent contains h_addr_list])
fi

# Check for types
AC_TYPE_PID_T

# Check for the functions needed to create a new session.
# Note that getsid may not have a prototype in unistd.h unless
# _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED are defined, or
# if _XOPEN_SOURCE is defined as an integer 500 or larger (this
# for glibc).  The prototype should be
# pid_t getsid( pid_t pid );
#
# Cygwin has setsid but not getsid
AC_CHECK_FUNCS(setsid isatty getsid)
if test "$enable_newsession" = "yes" ; then
    AC_DEFINE(USE_NEW_SESSION,1,[Define if mpiexec should create a new process group session])
fi
if test "$ac_cv_func_getsid" = "yes" ; then
    # Check for prototype
    AC_CACHE_CHECK([whether getsid is prototyped in unistd.h],
    pac_cv_func_getsid_has_prototype,[
    AC_TRY_COMPILE([
#include <unistd.h>],[double a = getsid("string",1);],
   pac_cv_func_getsid_has_prototype=no,pac_cv_func_getsid_has_prototype=yes)])
    if test "$pac_cv_func_getsid_has_prototype" = no ; then
        AC_DEFINE(NEEDS_GETSID_PROTOTYPE,1,[Define if getsid needs a prototype])
    fi
fi
# Check for convenient functions for the environment
AC_CHECK_FUNCS(unsetenv)

# Check for cygwin1.dll in /bin.  If found, define NEEDS_BIN_IN_PATH because
# we need to include bin in the path when spawning programs.
# This is the simplest possible test; lets hope that it is sufficient
AC_CACHE_CHECK([for cygwin1.dll in /bin],pac_cv_needs_bin_in_path,[
pac_cv_needs_bin_in_path=no
if test /bin/cygwin1.dll ; then 
    pac_cv_needs_bin_in_path=yes
fi])
if test "$pac_cv_needs_bin_in_path" = yes ; then
    AC_DEFINE(NEEDS_BIN_IN_PATH,1,[Define if /bin must be in path])
fi

# Look for alternatives.  Is environ in unistd.h?
AC_CACHE_CHECK([for environ in unistd.h],pac_cv_has_environ_in_unistd,[
AC_TRY_COMPILE([#include <unistd.h>],[char **ep = environ;],
pac_cv_has_environ_in_unistd=yes,pac_cv_has_environ_in_unistd=no)])

if test "$pac_cv_has_environ_in_unistd" != "yes" ; then
    # Can we declare it and use it?
    AC_CACHE_CHECK([for extern environ in runtime],
    pac_cv_has_extern_environ,[
    AC_TRY_LINK([extern char **environ;],[char **ep = environ;],
    pac_cv_has_extern_environ=yes,pac_cv_has_extern_environ=no)])
    if test "$pac_cv_has_extern_environ" = "yes" ; then
	AC_DEFINE(NEEDS_ENVIRON_DECL,1,[Define if environ decl needed] )
    fi
else
    pac_cv_has_extern_environ=yes
fi
if test "$pac_cv_has_extern_environ" = "yes" ; then
    AC_DEFINE(HAVE_EXTERN_ENVIRON,1,[Define if environ extern is available])
fi
dnl
dnl Check for special compile characteristics
dnl
dnl Is there libnsl needed for gethostbyname?
dnl AC_SEARCH_LIBS(gethostbyname,nsl)
AC_SEARCH_LIBS(socketpair,socket)
dnl
dnl Look for Standard headers
AC_HEADER_STDC
dnl Check for a specific header
AC_CHECK_HEADERS(sys/types.h signal.h sys/ptrace.h sys/uio.h unistd.h)
if test "$ac_cv_header_sys_uio_h" = "yes" ; then
    # Test for iovec defined
    AC_CACHE_CHECK([whether struct iovec is defined in sys/uio.h],
    pac_cv_has_struct_iovec,[
    AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/uio.h>],[struct iovec v],pac_cv_has_struct_iovec=yes,
pac_cv_has_struct_iovec=no)])
    if test "$pac_cv_has_struct_iovec" = "yes" ; then
        AC_DEFINE(HAVE_IOVEC_DEFINITION,1,[Define if struct iovec defined in sys/uio.h])
    fi
fi
dnl
dnl Check for functions.  This invokes another test if the function is 
dnl found.  The braces around the second test are essential. 
dnl AC_CHECK_FUNC(setpgrp,[AC_FUNC_SETPGRP])
AC_CHECK_FUNCS(strsignal)
if test "$ac_cv_func_strsignal" = "yes" ; then
    PAC_FUNC_NEEDS_DECL([#include <string.h>],strsignal)
fi
AC_CHECK_FUNCS(snprintf)
AC_CHECK_FUNCS(strdup)
dnl 
dnl Check for signal handlers
AC_CHECK_FUNCS(sigaction signal sigset)
sigaction_ok=no
if test "$ac_cv_func_sigaction" = "yes" ; then
    # Make sure that the fields that we need in sigaction are defined
    AC_CACHE_CHECK([for struct sigaction and sa_handler],
    pac_cv_struct_sigaction_with_sa_handler,[
    AC_TRY_COMPILE([#include <signal.h>],[
struct sigaction act; sigaddset( &act.sa_mask, SIGINT );
act.sa_handler = SIG_IGN;],
    pac_cv_struct_sigaction_with_sa_handler=yes,
    pac_cv_struct_sigaction_with_sa_handler=no)])
    if test "$pac_cv_struct_sigaction_with_sa_handler" = "no" ; then
        AC_CACHE_CHECK([for struct sigaction and sa_handler with _POSIX_SOURCE],
	pac_cv_struct_sigaction_with_sa_handler_needs_posix,[
        AC_TRY_COMPILE([#define _POSIX_SOURCE
#include <signal.h>],[
struct sigaction act; sigaddset( &act.sa_mask, SIGINT );
act.sa_handler = SIG_IGN;],
	pac_cv_struct_sigaction_with_sa_handler_needs_posix=yes,
	pac_cv_struct_sigaction_with_sa_handler_needs_posix=no)])
        if test "$pac_cv_struct_sigaction_with_sa_handler_needs_posix" = "yes" ; then
            sigaction_ok=yes
	fi
    else
        sigaction_ok=yes
    fi
fi
dnl
# Decide on the signal handler to use
if test "$ac_cv_func_sigaction" = "yes" -a "$sigaction_ok" = "yes" ; then
    if test "$pac_cv_struct_sigaction_with_sa_handler_needs_posix" = yes ; then
        AC_DEFINE(NEEDS_POSIX_FOR_SIGACTION,1,[Define if _POSIX_SOURCE needed to get sigaction])
    fi
    AC_DEFINE(USE_SIGACTION,,[Define if sigaction should be used to set signals])
elif test "$ac_cv_func_signal" = "yes" ; then
    AC_DEFINE(USE_SIGNAL,,[Define if signal should be used to set signals])
fi
dnl
# Check for needed declarations.  This must be after any step that might
# change the compilers behavior, such as the _POSIX_SOURCE test above
# FIXME: need to include the test, at least for any file that
# might set _POSIX_SOURCE
if test "$ac_cv_func_snprintf" = "yes" ; then
    PAC_FUNC_NEEDS_DECL([#include <stdio.h>],snprintf)
fi
if test "$ac_cv_func_strdup" = "yes" ; then
    # Do we need to declare strdup?
    PAC_FUNC_NEEDS_DECL([#include <string.h>],strdup)
fi
#
# Check for select and working FD_ZERO 
AC_CHECK_FUNCS(select)
AC_CHECK_HEADERS(sys/select.h)
if test "$ac_cv_func_select" != yes ; then
    AC_MSG_ERROR([select is required for the process manager utilities])
else
    # Check that FD_ZERO works.  Under the Darwin xlc (version 6) compiler,
    # FD_ZERO gets turned into a referece to __builtin_bzero, which is not
    # in the xlc libraries.  This is apparently due to xlc pretending that it
    # is GCC within the system header files (the same test that must 
    # succeed within the system header files to cause the declaration to
    # be __builtin_bzero fails outside of the header file).
    # (sys/select.h is POSIX)
    if test "$ac_cv_header_sys_select_h" = yes ; then
        AC_CACHE_CHECK([whether FD_ZERO works],pac_cv_fdzero_works,[
        AC_TRY_LINK([#include <sys/select.h>],[fd_set v; FD_ZERO(&v)],
        pac_cv_fdzero_works=yes,pac_cv_fdzero_works=no)])
        if test "$pac_cv_fdzero_works" != yes ; then
            AC_MSG_ERROR([Programs with FD_ZERO cannot be linked (check your system includes)])
	fi
    fi
fi

dnl Setup other replaceable values
MPILIBNAME=${MPILIBNAME:-"mpich"}
AC_SUBST(MPILIBNAME)

if test -z "$master_top_srcdir" ; then
   master_top_srcdir='${srcdir}/../../..'
fi
AC_SUBST(master_top_srcdir)

AC_CHECK_HEADERS(string.h sys/time.h time.h stdlib.h sys/socket.h wait.h errno.h)
# Check for socklen_t .  
# (note the conditional inclusion of sys/socket.h)
AC_CACHE_CHECK([whether socklen_t is defined (in sys/socket.h if present)],
pac_cv_have_socklen_t,[
AC_TRY_COMPILE([
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
]
typedef struct { double a; int b; } socklen_t;,[socklen_t a;a.a=1.0;],pac_cv_have_socklen_t=no,pac_cv_have_socklen_t=yes)])
if test "$pac_cv_have_socklen_t" = yes ; then
    AC_DEFINE(HAVE_SOCKLEN_T,1,[Define if socklen_t is available])
fi
AC_SUBST(MPILIBNAME)
AC_SUBST(CC)
AC_SUBST(CFLAGS)
AC_SUBST(CC_SHL)
AC_SUBST(C_LINK_SHL)
AC_SUBST(master_top_srcdir)
dnl
dnl Dependency handling
AC_SUBST(MAKE_DEPEND_C)
dnl
dnl Etags
AC_CHECK_PROGS(ETAGS,etags,true)
AC_SUBST(ETAGS)
AC_SUBST(ETAGSADD)
export ETAGS
export ETAGSADD
dnl
dnl We don't want the library in this directory to be shared, but we
dnl do want to avoid unsubstituted autoconf variables.
AC_SUBST(LIBTOOL)
dnl

dnl Allow the Makefile to refer to the top of the build dir
AC_SUBST(master_top_builddir)

PAC_UPDATE_BASE_CACHE

dnl Generate the Makefiles from Makefile.in
AC_OUTPUT(Makefile test/Makefile)
