Skip to content

Commit

Permalink
Autoconf: Fortran testing of C bindings
Browse files Browse the repository at this point in the history
This patch fixes some issues with testing of C bindings in Fortran.
Specifically, some tests are using a C compiler which may be
unconfigured, causing unexpected errors.

The autoconf script now uses the Fortran compiler to test these
bindings, rather than using the C compiler to test for their existence.
A new macro (AX_FC_CHECK_BIND_C) was added to run these tests.

This achieves the actual goal (test of Fortran binding) on top of the
original goal (availability of C function), while ensuring that the actual
compiler of interest (FC) is used in the test.

Two C-based tests are still present in the script for testing the size
of jmp_buf and sigjmp_buf.  The C compiler is now configured with the
AX_MPI macro, and is only used to determine the size of these structs.
  • Loading branch information
marshallward authored and adcroft committed Nov 9, 2022
1 parent d46de87 commit 522e7aa
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 12 deletions.
25 changes: 16 additions & 9 deletions ac/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ AC_FC_SRCEXT(f90)
# - This can cause standard AC_PROG_FC tests to fail if FCFLAGS is configured
# with flags from another compiler.
# - I do not yet know how to resolve this possible issue.
AX_MPI([],
[AC_MSG_ERROR([Could not find MPI launcher.])])
AX_MPI([], [
AC_MSG_ERROR([Could not find MPI launcher.])
])


# Explicitly replace FC and LD with MPI wrappers
Expand Down Expand Up @@ -233,13 +234,13 @@ AC_CONFIG_COMMANDS(Makefile.dep, [make depend])


# POSIX verification tests
AC_LANG_PUSH([C])

# These symbols may be defined as macros, making them inaccessible by Fortran.
# The following exist in BSD and Linux, so we just test for them.
AC_CHECK_FUNC([setjmp], [], [AC_MSG_ERROR([Could not find setjmp.])])
AC_CHECK_FUNC([longjmp], [], [AC_MSG_ERROR([Could not find longjmp.])])
AC_CHECK_FUNC([siglongjmp], [], [AC_MSG_ERROR([Could not find siglongjmp.])])
# These three exist in modern BSD and Linux libc, so we just confirm them.
# But one day, we many need to handle them more carefully.
AX_FC_CHECK_BIND_C([setjmp], [], [AC_MSG_ERROR([Could not find setjmp.])])
AX_FC_CHECK_BIND_C([longjmp], [], [AC_MSG_ERROR([Could not find longjmp.])])
AX_FC_CHECK_BIND_C([siglongjmp], [], [AC_MSG_ERROR([Could not find siglongjmp.])])

# Determine the sigsetjmp symbol. If missing, then point to sigsetjmp_missing.
#
Expand All @@ -248,14 +249,20 @@ AC_CHECK_FUNC([siglongjmp], [], [AC_MSG_ERROR([Could not find siglongjmp.])])
# __sigsetjmp glibc (Linux)
SIGSETJMP="sigsetjmp_missing"
for sigsetjmp_fn in sigsetjmp __sigsetjmp; do
AC_CHECK_FUNC([${sigsetjmp_fn}], [
AX_FC_CHECK_BIND_C([${sigsetjmp_fn}], [
SIGSETJMP=${sigsetjmp_fn}
break
])
done
AC_DEFINE_UNQUOTED([SIGSETJMP_NAME], ["${SIGSETJMP}"])

# Determine the size of jmp_buf and sigjmp_buf
# Verify the size of nonlocal jump buffer structs
# NOTE: This requires C compiler, but can it be done with a Fortran compiler?
AC_LANG_PUSH([C])

AX_MPI([], [AC_MSG_ERROR([Could not find MPI launcher.])])
AC_SUBST([CC], [$MPICC])

AC_CHECK_SIZEOF([jmp_buf], [], [#include <setjmp.h>])
AC_CHECK_SIZEOF([sigjmp_buf], [], [#include <setjmp.h>])

Expand Down
42 changes: 42 additions & 0 deletions ac/m4/ax_fc_check_bind_c.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
dnl AX_FC_CHECK_C_LIB(FUNCTION,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
dnl [OTHER-LDFLAGS], [OTHER-LIBS])
dnl
dnl This macro checks if a C binding is available to the compiler.
dnl
dnl Equivalently, it checks if the Fortran compiler can see a C function.
dnl
dnl Results are cached in `ax_fc_cv_bind_c_FUNCTION`.
dnl
AC_DEFUN([AX_FC_CHECK_BIND_C], [
AS_VAR_PUSHDEF([ax_fc_Bind_C], [ax_fc_cv_bind_c_$1])
m4_ifval([$4],
[ax_fc_bind_c_msg_LDFLAGS=" with $4"],
[ax_fc_bind_c_msg_LDFLAGS=""]
)
AC_CACHE_CHECK(
[if $FC can bind $1$ax_fc_bind_c_msg_LDFLAGS], [ax_fc_cv_bind_c_$1], [
ax_fc_check_bind_c_save_LDFLAGS=$LDFLAGS
LDFLAGS="$4 $LDFLAGS"
ax_fc_check_bind_c_save_LIBS=$LIBS
LIBS="$5 $LIBS"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([],[dnl
dnl begin code block
interface
subroutine test() bind(c, name="$1")
end subroutine test
end interface
call test])
dnl end code block
],
[AS_VAR_SET([ax_fc_Bind_C], [yes])],
[AS_VAR_SET([ax_fc_Bind_C], [no])]
)
LDFLAGS=$ax_fc_check_bind_c_save_LDFLAGS
LIBS=$ax_fc_check_bind_c_save_LIBS
]
)
AS_VAR_IF([ax_fc_Bind_C], [yes], [$2], [$3])
AS_VAR_POPDEF([ax_fc_Bind_C])
])
6 changes: 3 additions & 3 deletions ac/m4/ax_fc_check_c_lib.m4
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ dnl AX_FC_CHECK_C_LIB(LIBRARY, FUNCTION,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
dnl [OTHER-LDFLAGS], [OTHER-LIBS])
dnl
dnl This macro checks if a C binding is available to the compiler.
dnl
dnl Equivalently, it checks if the Fortran compiler can see a C function.
dnl This macro checks if a C library can be referenced by a Fortran compiler.
dnl
dnl Results are cached in `ax_fc_cv_c_lib_LIBRARY_FUNCTION`.
dnl
dnl NOTE: Might be possible to rewrite this to use `AX_FC_CHECK_BIND_C`.
dnl
AC_DEFUN([AX_FC_CHECK_C_LIB], [
AS_VAR_PUSHDEF([ax_fc_C_Lib], [ax_fc_cv_c_lib_$1_$2])
m4_ifval([$5],
Expand Down

0 comments on commit 522e7aa

Please sign in to comment.