Revision 80f2b368e3011f2676f42c66e989504772338554 authored by Eh Tan on 16 October 2013, 05:09:46 UTC, committed by Eh Tan on 16 October 2013, 05:09:46 UTC
1 parent 90690a9
cit_petsc.m4
# -*- Autoconf -*-
## -------------------------- ##
## Autoconf macros for PETSc. ##
## -------------------------- ##
# CIT_PATH_PETSC([VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -----------------------------------------------------------------------
# Check for the PETSc package. Requires Python.
AC_DEFUN([CIT_PATH_PETSC], [
# $Id$
AC_REQUIRE([AM_PATH_PYTHON])
AC_ARG_VAR(PETSC_DIR, [location of PETSc installation])
AC_ARG_VAR(PETSC_ARCH, [PETSc configuration])
AC_MSG_CHECKING([for PETSc dir])
if test -z "$PETSC_DIR"; then
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([PETSc not found; set PETSC_DIR])])
elif test ! -d "$PETSC_DIR"; then
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([PETSc not found; PETSC_DIR=$PETSC_DIR is invalid])])
elif test ! -d "$PETSC_DIR/include"; then
AC_MSG_RESULT(broken)
m4_default([$3], [AC_MSG_ERROR([PETSc include dir $PETSC_DIR/include not found; check PETSC_DIR])])
elif test ! -f "$PETSC_DIR/include/petscversion.h"; then
AC_MSG_RESULT(broken)
m4_default([$3], [AC_MSG_ERROR([PETSc header file $PETSC_DIR/include/petscversion.h not found; check PETSC_DIR])])
fi
AC_MSG_RESULT([$PETSC_DIR])
# In what follows, we consistenly check for the new config layout
# first, in case the user is using an old HG working copy with junk in
# it.
AC_MSG_CHECKING([for PETSc arch])
if test -z "$PETSC_ARCH"; then
if test -d "$PETSC_DIR/conf"; then
# new config layout; no default config (?)
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([set PETSC_ARCH])])
elif test ! -f "$PETSC_DIR/bmake/petscconf"; then
# old config layout (2.3.3 and earlier)
AC_MSG_RESULT(error)
m4_default([$3], [AC_MSG_ERROR([PETSc file $PETSC_DIR/bmake/petscconf not found; check PETSC_DIR])])
else
cat >petsc.py <<END_OF_PYTHON
[from distutils.sysconfig import parse_makefile
vars = parse_makefile('$PETSC_DIR/bmake/petscconf')
print 'PETSC_ARCH="%s"' % vars['PETSC_ARCH']
]
END_OF_PYTHON
eval `$PYTHON petsc.py 2>/dev/null`
rm -f petsc.py
fi
fi
AC_MSG_RESULT([$PETSC_ARCH])
AC_MSG_CHECKING([for PETSc config])
if test -d "$PETSC_DIR/$PETSC_ARCH/conf"; then
if test -f "$PETSC_DIR/$PETSC_ARCH/conf/petscvariables"; then
cit_petsc_petscconf="$PETSC_DIR/$PETSC_ARCH/conf/petscvariables"
elif test -f "$PETSC_DIR/$PETSC_ARCH/conf/petscconf"; then
cit_petsc_petscconf="$PETSC_DIR/$PETSC_ARCH/conf/petscconf"
else
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([Could not find file with PETSc configuration settings; check PETSC_ARCH/conf])])
fi
# installed PETSc
elif test -d "$PETSC_DIR/conf"; then
if test -f "$PETSC_DIR/conf/petscvariables"; then
cit_petsc_petscconf="$PETSC_DIR/conf/petscvariables"
else
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([Could not find file with PETSc configuration settings; check PETSC_DIR/conf])])
fi
# Using conf/variables *should* be obsolete for new config.
#cit_petsc_variables="$PETSC_DIR/conf/variables"
elif test -d "$PESC_DIR/bmake/$PETSC_ARCH"; then
# old config layout
cit_petsc_petscconf="$PETSC_DIR/bmake/$PETSC_ARCH/petscconf"
cit_petsc_variables="$PETSC_DIR/bmake/common/variables"
if test ! -f "$cit_petsc_variables"; then
AC_MSG_RESULT(error)
m4_default([$3], [AC_MSG_ERROR([PETSc config file $cit_petsc_variables not found; check PETSC_DIR])])
fi
else
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([PETSc config dir not found; check PETSC_ARCH])])
fi
if test ! -f "$cit_petsc_petscconf"; then
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([PETSc config file $cit_petsc_petscconf not found; check PETSC_ARCH])])
fi
AC_MSG_RESULT([$cit_petsc_petscconf])
AC_MSG_CHECKING([for PETSc version == $1])
echo "PETSC_DIR = $PETSC_DIR" > petscconf
echo "PETSC_ARCH = $PETSC_ARCH" >> petscconf
cat $cit_petsc_petscconf $cit_petsc_variables >> petscconf
cat >petsc.py <<END_OF_PYTHON
[from distutils.sysconfig import parse_config_h, parse_makefile, expand_makefile_vars
f = open('$PETSC_DIR/include/petscversion.h')
vars = parse_config_h(f)
f.close()
parse_makefile('petscconf', vars)
keys = (
'PETSC_VERSION_MAJOR',
'PETSC_VERSION_MINOR',
'PETSC_VERSION_SUBMINOR',
'PETSC_CC_INCLUDES',
'PETSC_FC_INCLUDES',
'PETSC_LIB',
'PETSC_FORTRAN_LIB',
'CC',
'CXX',
'FC',
'MPI_LIB',
'MPI_INCLUDE',
'SIEVE_FLAGS',
)
for key in keys:
if key[:6] == 'PETSC_':
value = expand_makefile_vars(str(vars.get(key, '')), vars)
if key == 'PETSC_LIB':
# Libtool strips the former. (Does it ever work?)
value = value.replace("/System/Library/Frameworks/vecLib.framework/vecLib",
"-Wl,-framework,vecLib")
print '%s="%s"' % (key, value)
else:
print 'PETSC_%s="%s"' % (key, expand_makefile_vars(str(vars.get(key, '')), vars))
]
END_OF_PYTHON
AS_IF([AC_TRY_COMMAND([$PYTHON petsc.py >conftest.sh 2>&AS_MESSAGE_LOG_FD])],
[],
[AC_MSG_RESULT(error)
AC_MSG_FAILURE([cannot parse PETSc configuration])])
eval `cat conftest.sh`
rm -f conftest.sh petsc.py petscconf
[eval `echo $1 | sed 's/\([^.]*\)[.]\([^.]*\)[.]\([^.]*\).*/petsc_1_major=\1; petsc_1_minor=\2; petsc_1_subminor=\3;/'`]
if test -z "$PETSC_VERSION_MAJOR" -o -z "$PETSC_VERSION_MINOR" -o -z "$PETSC_VERSION_SUBMINOR"; then
AC_MSG_RESULT(no)
m4_default([$3], [AC_MSG_ERROR([no suitable PETSc package found])])
elif test "$PETSC_VERSION_MAJOR" -eq "$petsc_1_major" -a \
"$PETSC_VERSION_MINOR" -eq "$petsc_1_minor" -a \
"$PETSC_VERSION_SUBMINOR" -eq "$petsc_1_subminor" ; then
AC_MSG_RESULT(yes)
$2
else
AC_MSG_RESULT([no ($PETSC_VERSION_MAJOR.$PETSC_VERSION_MINOR.$PETSC_VERSION_SUBMINOR)])
m4_default([$3], [AC_MSG_ERROR([no suitable PETSc package found])])
fi
AC_SUBST([PETSC_VERSION_MAJOR])
AC_SUBST([PETSC_VERSION_MINOR])
AC_SUBST([PETSC_VERSION_SUBMINOR])
AC_SUBST([PETSC_CC_INCLUDES])
AC_SUBST([PETSC_FC_INCLUDES])
AC_SUBST([PETSC_LIB])
AC_SUBST([PETSC_FORTRAN_LIB])
AC_SUBST([PETSC_CC])
AC_SUBST([PETSC_CXX])
AC_SUBST([PETSC_FC])
AC_SUBST([PETSC_MPI_LIB])
AC_SUBST([PETSC_MPI_INCLUDE])
AC_SUBST([PETSC_SIEVE_FLAGS])
])dnl CIT_PATH_PETSC
# CIT_CHECK_LIB_PETSC
# -------------------
# Try to link against the PETSc libraries. If the current language is
# C++, determine the value of PETSC_CXX_LIB, which names the extra
# libraries needed when using a C++ compiler. (As of PETSc v2.3,
# PETSC_CXX_LIB will always be empty; see comment below.)
AC_DEFUN([CIT_CHECK_LIB_PETSC], [
# $Id$
AC_REQUIRE([CIT_PATH_PETSC])dnl
AC_SUBST(PETSC_CXX_LIB)
PETSC_CXX_LIB=
cit_petsc_save_CC=$CC
cit_petsc_save_LIBS=$LIBS
CC=$PETSC_CC
LIBS="$PETSC_LIB $LIBS"
_CIT_LINK_PETSC_IFELSE([], [
AC_LANG_CASE(
[C++], [],
_CIT_CHECK_LIB_PETSC_FAILED
)
#
# Try to guess the correct value for PETSC_CXX_LIB, assuming PETSC_CC
# is an MPI wrapper.
#
# In theory, when PETSC_CC is 'mpicc', *both* the MPI libraries and
# includes are effectively hidden, and must be extracted in order to
# use a C++ compiler (the PETSc configuration does not specify a C++
# compiler command).
#
# But this path was only added for symmetry with CIT_HEADER_PETSC.
# Because, in practice, there is an asymmetry between includes and
# libs. When PETSC_CC is 'mpicc', the MPI includes are indeed hidden:
# PETSC_INCLUDE omits MPI includes. But PETSC_LIB always explicitly
# specifies the MPI library, even (redundantly) when PETSC_CC is
# 'mpicc'. So, as of PETSc v2.3 at least, this path is never taken.
CIT_MPI_LIBS(cit_libs, $PETSC_CC, [
LIBS="$PETSC_LIB $cit_libs $cit_petsc_save_LIBS"
unset ac_cv_func_PetscInitialize
_CIT_LINK_PETSC_IFELSE([
PETSC_CXX_LIB=$cit_libs
], [
_CIT_CHECK_LIB_PETSC_FAILED
])
], [
_CIT_CHECK_LIB_PETSC_FAILED
])
])
LIBS=$cit_petsc_save_LIBS
CC=$cit_petsc_save_CC
])dnl CIT_CHECK_LIB_PETSC
# _CIT_CHECK_LIB_PETSC_FAILED
# ---------------------------
AC_DEFUN([_CIT_CHECK_LIB_PETSC_FAILED], [
AC_MSG_ERROR([cannot link against PETSc libraries])
])dnl _CIT_CHECK_LIB_PETSC_FAILED
# _CIT_LINK_PETSC_IFELSE([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ----------------------------------------------------------------
AC_DEFUN([_CIT_LINK_PETSC_IFELSE], [
# PetscInitialize() might have C++ linkage. If the current language
# is C++, allow for this possibility.
AC_LANG_CASE(
[C++], [
AC_MSG_CHECKING([for PetscInitialize])
AC_LINK_IFELSE(_CIT_CHECK_LIB_PETSC_PROGRAM([]), [
AC_MSG_RESULT([yes (C++)])
$1
], [
AC_LINK_IFELSE(_CIT_CHECK_LIB_PETSC_PROGRAM([extern "C"]), [
AC_MSG_RESULT([yes (C)])
$1
], [
AC_MSG_RESULT(no)
$2
])
])
],
[AC_CHECK_FUNC(PetscInitialize, [$1], [$2])]
)
])dnl _CIT_LINK_PETSC_IFELSE
# _CIT_CHECK_LIB_PETSC_PROGRAM
# ----------------------------
AC_DEFUN([_CIT_CHECK_LIB_PETSC_PROGRAM], [
AC_LANG_PROGRAM([[
$1 int PetscInitialize(int *, char ***,const char *,const char *);
]], [[
PetscInitialize(0, 0, 0, "checklib");
]])
])dnl _CIT_CHECK_LIB_PETSC_PROGRAM
# CIT_HEADER_PETSC
# ----------------
# Try to use PETSc headers. If the current language is C++, determine
# the value of PETSC_CXX_INCLUDE, which names the extra include paths
# needed when using a C++ compiler... i.e., the MPI includes. When
# PETSC_CC is set to an MPI wrapper such as 'mpicc', the required MPI
# includes are effectively hidden, and must be extracted in order to
# use a C++ compiler (the PETSc configuration does not specify a C++
# compiler command).
AC_DEFUN([CIT_HEADER_PETSC], [
# $Id$
AC_REQUIRE([CIT_PATH_PETSC])dnl
AC_REQUIRE([CIT_CHECK_LIB_PETSC])dnl
AC_SUBST(PETSC_CXX_INCLUDE)
PETSC_CXX_INCLUDE=
cit_petsc_save_CC=$CC
cit_petsc_save_CPPFLAGS=$CPPFLAGS
cit_petsc_save_LIBS=$LIBS
CC=$PETSC_CC
CPPFLAGS="$PETSC_CC_INCLUDES $CPPFLAGS"
AC_MSG_CHECKING([for petsc.h])
dnl Use AC_TRY_COMPILE instead of AC_CHECK_HEADER because the
dnl latter also preprocesses using $CXXCPP.
AC_TRY_COMPILE([
#include <petsc.h>
], [], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_LANG_CASE(
[C++], [],
_CIT_HEADER_PETSC_FAILED
)
# Try to guess the correct value for PETSC_CXX_INCLUDE, assuming
# PETSC_CC is an MPI wrapper.
CIT_MPI_INCLUDES(cit_includes, $PETSC_CC, [
AC_MSG_CHECKING([for petsc.h])
CPPFLAGS="$PETSC_CC_INCLUDES $cit_includes $cit_petsc_save_CPPFLAGS"
AC_TRY_COMPILE([
#include <petsc.h>
], [], [
AC_MSG_RESULT(yes)
PETSC_CXX_INCLUDE=$cit_includes
], [
AC_MSG_RESULT(no)
_CIT_HEADER_PETSC_FAILED
])
], [
_CIT_HEADER_PETSC_FAILED
])
])
AC_LANG_CASE([C++], [
LIBS="$PETSC_LIB $PETSC_CXX_LIB $LIBS"
CIT_MPI_CHECK_CXX_LINK(PETSC_CXX_INCLUDE, [$PETSC_LIB],
_CIT_TRIVIAL_PETSC_PROGRAM,
[whether we can link a trivial C++ PETSc program],
[],
AC_MSG_FAILURE([cannot link a trivial C++ PETSc program using $CXX]))
])
LIBS=$cit_petsc_save_LIBS
CPPFLAGS=$cit_petsc_save_CPPFLAGS
CC=$cit_petsc_save_CC
])dnl CIT_HEADER_PETSC
# _CIT_HEADER_PETSC_FAILED
# ------------------------
AC_DEFUN([_CIT_HEADER_PETSC_FAILED], [
AC_MSG_ERROR([header "petsc.h" not found])
])dnl _CIT_HEADER_PETSC_FAILED
# _CIT_TRIVIAL_PETSC_PROGRAM
# --------------------------
AC_DEFUN([_CIT_TRIVIAL_PETSC_PROGRAM], [
AC_LANG_PROGRAM([[
#include <petsc.h>
]], [[
PetscInitialize(0, 0, 0, "trivial");
PetscFinalize();
]])
])dnl _CIT_TRIVIAL_PETSC_PROGRAM
# CIT_CHECK_LIB_PETSC_SIEVE
# -------------------------
AC_DEFUN([CIT_CHECK_LIB_PETSC_SIEVE], [
AC_MSG_CHECKING([for PETSc/Sieve])
AC_LANG_PUSH(C++)
cit_petsc_save_LIBS=$LIBS
cit_petsc_save_CPPFLAGS=$CPPFLAGS
LIBS="$PETSC_LIB $PETSC_CXX_LIB $LIBS"
CPPFLAGS="$PETSC_CC_INCLUDES $PETSC_CXX_INCLUDE $CPPFLAGS"
AC_LINK_IFELSE(AC_LANG_PROGRAM([[
#include <petscdmmesh.hh>
]], [[
const int dim = 3;
ALE::Mesh<int,double> mesh(PETSC_COMM_WORLD, dim);
]]), [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_MSG_FAILURE([cannot build a trivial C++ PETSc program which uses ALE::Sieve])
])
CPPFLAGS=$cit_petsc_save_CPPFLAGS
LIBS=$cit_petsc_save_LIBS
AC_LANG_POP(C++)
])dnl CIT_CHECK_LIB_PETSC_SIEVE
dnl end of file

Computing file changes ...