This macro caches its result in the @code{ac_cv_prog_c_openmp},
@code{ac_cv_prog_cxx_openmp}, @code{ac_cv_prog_f77_openmp}, or
@code{ac_cv_prog_fc_openmp} variable, depending on the current language.
+
+@strong{Caution:} Some of the compiler options that @code{AC_OPENMP}
+tests, mean ``enable OpenMP'' to one compiler, but ``write output to a
+file named @file{mp} or @file{penmp}'' to other compilers. We cannot
+guarantee that the implementation of @code{AC_OPENMP} will not overwrite
+an existing file with either of these names.
+
+Therefore, as a defensive measure, a @command{configure} script that
+uses @code{AC_OPENMP} will issue an error and stop (before doing any of
+the operations that might overwrite these files) upon encountering
+either of these files in its working directory.
+@command{autoconf} will also issue an error if it finds either of
+these files in the same directory as a @file{configure.ac} that
+uses @code{AC_OPENMP}.
+
+If you have files with either of these names at the top level of your
+source tree, and you need to use @code{AC_OPENMP}, we recommend you
+either change their names or move them into a subdirectory.
@end defmac
@node C Compiler
m4_define([_AC_LANG_OPENMP(C)],
[
#ifndef _OPENMP
- choke me
+#error "OpenMP not supported"
#endif
#include <omp.h>
int main (void) { return omp_get_num_threads (); }
# The options are necessary at compile time (so the #pragmas are understood)
# and at link time (so the appropriate library is linked with).
# This macro takes care to not produce redundant options if $CC $CFLAGS already
-# supports OpenMP. It also is careful to not pass options to compilers that
-# misinterpret them; for example, most compilers accept "-openmp" and create
-# an output file called 'penmp' rather than activating OpenMP support.
+# supports OpenMP.
+#
+# For each candidate option, we do a compile test first, then a link test;
+# if the compile test succeeds but the link test fails, that means we have
+# found the correct option but it doesn't work because the libraries are
+# broken. (This can happen, for instance, with SunPRO C and a bad combination
+# of operating system patches.)
+#
+# Several of the options in our candidate list can be misinterpreted by
+# compilers that don't use them to activate OpenMP support; for example,
+# many compilers understand "-openmp" to mean "write output to a file
+# named 'penmp'" rather than "enable OpenMP". We can't completely avoid
+# the possibility of clobbering files named 'penmp' or 'mp' in configure's
+# working directory; therefore, this macro will bomb out if any such file
+# already exists when it's invoked.
AC_DEFUN([AC_OPENMP],
+[AC_REQUIRE([_AC_OPENMP_SAFE_WD])]dnl
+[AC_ARG_ENABLE([openmp],
+ [AS_HELP_STRING([--disable-openmp], [do not use OpenMP])])]dnl
[
OPENMP_[]_AC_LANG_PREFIX[]FLAGS=
- AC_ARG_ENABLE([openmp],
- [AS_HELP_STRING([--disable-openmp], [do not use OpenMP])])
if test "$enable_openmp" != no; then
AC_CACHE_CHECK([for $[]_AC_CC[] option to support OpenMP],
[ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp],
- [AC_LINK_IFELSE([_AC_LANG_OPENMP],
- [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='none needed'],
- [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported'
- dnl Try these flags:
- dnl GCC >= 4.2 -fopenmp
- dnl SunPRO C -xopenmp
- dnl Intel C -openmp
- dnl SGI C, PGI C -mp
- dnl Tru64 Compaq C -omp
- dnl IBM XL C (AIX, Linux) -qsmp=omp
- dnl Cray CCE -homp
- dnl NEC SX -Popenmp
- dnl Lahey Fortran (Linux) --openmp
- dnl If in this loop a compiler is passed an option that it doesn't
- dnl understand or that it misinterprets, the AC_LINK_IFELSE test
- dnl will fail (since we know that it failed without the option),
- dnl therefore the loop will continue searching for an option, and
- dnl no output file called 'penmp' or 'mp' is created.
- for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \
- -Popenmp --openmp; do
- ac_save_[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
- _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $ac_option"
- AC_LINK_IFELSE([_AC_LANG_OPENMP],
- [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp=$ac_option])
- _AC_LANG_PREFIX[]FLAGS=$ac_save_[]_AC_LANG_PREFIX[]FLAGS
- if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != unsupported; then
- break
- fi
- done])])
- case $ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp in #(
- "none needed" | unsupported)
- ;; #(
- *)
- OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp ;;
- esac
+ [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='not found'
+ dnl Try these flags:
+ dnl (on by default) ''
+ dnl GCC >= 4.2 -fopenmp
+ dnl SunPRO C -xopenmp
+ dnl Intel C -openmp
+ dnl SGI C, PGI C -mp
+ dnl Tru64 Compaq C -omp
+ dnl IBM XL C (AIX, Linux) -qsmp=omp
+ dnl Cray CCE -homp
+ dnl NEC SX -Popenmp
+ dnl Lahey Fortran (Linux) --openmp
+ for ac_option in '' -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \
+ -Popenmp --openmp; do
+
+ ac_save_[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $ac_option"
+ AC_COMPILE_IFELSE([_AC_LANG_OPENMP],
+ [AC_LINK_IFELSE([_AC_LANG_OPENMP],
+ [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp=$ac_option],
+ [ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported'])])
+ _AC_LANG_PREFIX[]FLAGS=$ac_save_[]_AC_LANG_PREFIX[]FLAGS
+
+ if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'not found'; then
+ break
+ fi
+ done
+ if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" = 'not found'; then
+ ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='unsupported'
+ elif test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" = ''; then
+ ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp='none needed'
+ fi
+ dnl _AC_OPENMP_SAFE_WD checked that these files did not exist before we
+ dnl started probing for OpenMP support, so if they exist now, they were
+ dnl created by the probe loop and it's safe to delete them.
+ rm -f penmp mp])
+ if test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'unsupported' && \
+ test "$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp" != 'none needed'; then
+ OPENMP_[]_AC_LANG_PREFIX[]FLAGS="$ac_cv_prog_[]_AC_LANG_ABBREV[]_openmp"
+ fi
fi
AC_SUBST([OPENMP_]_AC_LANG_PREFIX[FLAGS])
])
+# _AC_OPENMP_SAFE_WD
+# ------------------
+# AC_REQUIREd by AC_OPENMP. Checks both at autoconf time and at
+# configure time for files that AC_OPENMP clobbers.
+AC_DEFUN([_AC_OPENMP_SAFE_WD],
+[m4_syscmd([test ! -e penmp && test ! -e mp])]dnl
+[m4_if(sysval, [0], [], [m4_fatal(m4_normalize(
+ [AC_OPENMP clobbers files named 'mp' and 'penmp'.
+ To use AC_OPENMP you must not have either of these files
+ at the top level of your source tree.]))])]dnl
+[if test -e penmp || test -e mp; then
+ AC_MSG_ERROR(m4_normalize(
+ [AC@&t@_OPENMP clobbers files named 'mp' and 'penmp'.
+ Aborting configure because one of these files already exists.]))
+fi])
+
+
+
# _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
# ----------------------------------------------------------------
AT_CHECK_CONFIGURE
AT_CLEANUP
+
+## ------------------------------ ##
+## Files clobbered by AC_OPENMP. ##
+## ------------------------------ ##
+
+AT_SETUP([Files clobbered by AC_OPENMP])
+
+AT_CONFIGURE_AC(
+[[AC_PROG_CC
+AC_OPENMP
+]])
+
+AT_CHECK_AUTOHEADER
+
+# autoconf should bomb out if either 'mp' or 'openmp' exists in the
+# srcdir.
+AT_DATA([mp])
+AT_CHECK_AUTOCONF([], [1], [], [stderr])
+AT_CHECK([grep "clobbers files named 'mp' and 'penmp'" stderr],
+ [0], [ignore], [ignore])
+rm -f mp
+
+AT_DATA([penmp])
+AT_CHECK_AUTOCONF([], [1], [], [stderr])
+AT_CHECK([grep "clobbers files named 'mp' and 'penmp'" stderr],
+ [0], [ignore], [ignore])
+rm -f penmp
+
+# If neither of these files exist, autoconf should go through...
+AT_CHECK_AUTOCONF
+
+# ... but configure should bomb out, and *not* delete the files,
+# if they are added after autoconf is run.
+AT_DATA([mp])
+AT_CHECK_CONFIGURE([], [1], [], [stderr])
+AT_CHECK([test -e mp])
+AT_CHECK([grep "clobbers files named 'mp' and 'penmp'" stderr],
+ [0], [ignore], [ignore])
+rm -f mp
+
+AT_DATA([penmp])
+AT_CHECK_CONFIGURE([], [1], [], [stderr])
+AT_CHECK([test -e penmp])
+AT_CHECK([grep "clobbers files named 'mp' and 'penmp'" stderr],
+ [0], [ignore], [ignore])
+rm -f penmp
+
+AT_CHECK_CONFIGURE
+AT_CHECK_ENV
+
+AT_CLEANUP