A not-unfrequent problem we have with Open MPI is users specifying incompatible compiler flags for the different languages used in Open MPI. This frequently occurs when a user wants to build 64-bit on a system that defaults to 32-bit and provides the right CFLAGS, but skips one of the FFLAGS, FCFLAGS, CXXFLAGS, or OBJCFLAGS. If you’re lucky, you’ll get an amorphous error during configure time saying something completely unrelated to the original problem went wrong. If you’re unlucky, nothing bad will happen until you try to link ompi_info, which is one of the last things that gets built.
I wrote a macro for Open MPI today that tries to link a small C function in a .o file with a main function in either Fortran (either 90 or 77) or one of the C-like languages (C++ / Objective C) to see if they link. The result is not pretty, and I’m hoping there’s a better way to do this, but this is what I came up with (below). The only part I’m really not happy with is all the code to deal with the Fortran calling. I’m sure there’s a better way than defining a particular m4 variable then looking at that for the rest of the function. But such is life…
dnl -*- shell-script -*-
dnl
dnl Copyright (c) 2006 Los Alamos National Security, LLC. All rights
dnl reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
dnl
dnl $HEADER$
dnl
# OMPI_LANG_LINK_WITH_C(language)
# -------------------------------
# Try to link a small test program against a C object file to make
# sure the compiler for the given language is compatible with the C
# compiler.
AC_DEFUN([OMPI_LANG_LINK_WITH_C], [
AS_VAR_PUSHDEF([lang_var], [ompi_cv_c_link_$1])
AC_CACHE_CHECK([if C and $1 are link compatible],
lang_var,
[m4_if([$1], [Fortran],
[m4_define([ompi_lang_link_with_c_fortran], 1)],
[m4_if([$1], [Fortran 77],
[m4_define([ompi_lang_link_with_c_fortran], 1)],
[m4_define([ompi_lang_link_with_c_fortran], 0)])])
m4_if(ompi_lang_link_with_c_fortran, 1,
[OMPI_F77_MAKE_C_FUNCTION([testfunc_name], [testfunc])],
[testfunc_name="testfunc"])
# Write out C part
AC_LANG_PUSH(C)
rm -f conftest_c.$ac_ext
cat > conftest_c.$ac_ext << EOF
int $testfunc_name(int a);
int $testfunc_name(int a) { return a; }
EOF
# Now compile both parts
OMPI_LOG_COMMAND([$CC -c $CFLAGS $CPPFLAGS conftest_c.$ac_ext],
[AC_LANG_PUSH($1)
ompi_lang_link_with_c_libs="$LIBS"
LIBS="conftest_c.o $LIBS"
ompi_lang_link_with_c_fortran
m4_if(ompi_lang_link_with_c_fortran, 1,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
external testfunc
call testfunc(1)
])],
[AS_VAR_SET(lang_var, ["yes"])], [AS_VAR_SET(lang_var, ["no"])])],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" int testfunc(int);
#else
extern int testfunc(int);
#endif
],
[return testfunc(0);])],
[AS_VAR_SET(lang_var, ["yes"])], [AS_VAR_SET(lang_var, ["no"])])])
LIBS="$ompi_lang_link_with_c_libs"
AC_LANG_POP($1)],
[AS_VAR_SET(lang_var, ["no"])])
rm -f conftest_c.$ac_ext
AC_LANG_POP(C)])
AS_IF([test "AS_VAR_GET([lang_var])" = "yes"], [$2], [$3])
AS_VAR_POPDEF([lang_var])dnl
])