# -*- Autotest -*- AT_BANNER([Fortran low level compiling/preprocessing macros.]) # Copyright (C) 2000-2001, 2003, 2008-2017, 2020-2021 Free Software # Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Since the macros which compile are required by most tests, check # them first. But remember that looking for a compiler is even more # primitive, so check those first. ## --------------------- ## ## Fortran 77 Compiler. ## ## --------------------- ## AT_CHECK_MACRO([GNU Fortran 77], [[AC_LANG(Fortran 77) AC_LANG_COMPILER : > conftest.f if AC_TRY_COMMAND([$F77 --version | grep GNU >&2]) \ || AC_TRY_COMMAND([$F77 -v -c conftest.f 2>&1 | grep "f2c " >&2]); then # Be sure to remove files which might be created by compilers that # don't support --version, or by the second compile. rm -f a.exe a.out conftest.f conftest.$ac_objext # Has GNU in --version. test "$G77" != yes && AC_MSG_ERROR([failed to recognize GNU Fortran 77 compiler]) else # Be sure to remove files which might be created by compilers that # don't support --version, or by the second compile. rm -f a.exe a.out conftest.f conftest.$ac_objext # Has not. test "$G77" = yes && AC_MSG_ERROR([incorrectly recognized a GNU Fortran 77 compiler]) fi ]]) ## ------------------ ## ## Fortran Compiler. ## ## ------------------ ## AT_CHECK_MACRO([GNU Fortran], [[AC_LANG(Fortran) AC_LANG_COMPILER # No Fortran compiler is known not to support "*.f". AC_FC_SRCEXT([f]) # GNU Fortran is known to support freeform. AC_FC_FREEFORM([], [AC_MSG_WARN([Fortran does not accept free-form source])]) if test "$ac_compiler_gnu" = yes; then case $FCFLAGS in *-ffree-form*) ;; *) AC_MSG_ERROR([failed to recognize GNU Fortran's -ffree-form option]);; esac fi ]]) ## ------------------------- ## ## AC_OPENMP and Fortran 77. ## ## ------------------------- ## AT_SETUP([AC_OPENMP and Fortran 77]) AT_DATA([configure.ac], [[AC_INIT AC_PROG_F77 AC_LANG([Fortran 77]) AC_OPENMP if test "X$ac_cv_prog_f77_openmp" = Xunsupported; then AS_EXIT([77]) fi FFLAGS="$FFLAGS $OPENMP_FFLAGS" AC_CONFIG_FILES([Makefile]) AC_OUTPUT ]]) AT_DATA([Makefile.in], [[foo@EXEEXT@: foo.@OBJEXT@ @F77@ @FFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ foo.@OBJEXT@: foo.f @F77@ @FFLAGS@ -c foo.f ]]) AT_DATA([foo.f], [[ program main end ]]) # Prevent autoreconf from running aclocal, which might not exist, # or could barf over warnings in third-party macro files. AT_DATA([aclocal.m4]) ACLOCAL=true export ACLOCAL AT_CHECK([autoreconf -vi], [], [ignore], [ignore]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CLEANUP ## ---------------------- ## ## AC_OPENMP and Fortran. ## ## ---------------------- ## AT_SETUP([AC_OPENMP and Fortran]) AT_DATA([configure.ac], [[AC_INIT AC_PROG_FC AC_LANG([Fortran]) AC_OPENMP if test "X$ac_cv_prog_fc_openmp" = Xunsupported; then AS_EXIT([77]) fi FCFLAGS="$FCFLAGS $OPENMP_FCFLAGS" AC_CONFIG_FILES([Makefile]) AC_OUTPUT ]]) AT_DATA([Makefile.in], [[foo@EXEEXT@: foo.@OBJEXT@ @FC@ @FCFLAGS@ @LDFLAGS@ -o $@ foo.@OBJEXT@ foo.@OBJEXT@: foo.f @FC@ @FCFLAGS@ -c foo.f ]]) AT_DATA([foo.f], [[ program main end ]]) # Prevent autoreconf from running aclocal, which might not exist, # or could barf over warnings in third-party macro files. AT_DATA([aclocal.m4]) ACLOCAL=true export ACLOCAL AT_CHECK([autoreconf -vi], [], [ignore], [ignore]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CLEANUP # We don't test the AC_F77_LIBRARY_LDFLAGS macro on its own because of # (autoconf.info)Fortran Compiler: # The macros `AC_F77_DUMMY_MAIN' and `AC_FC_DUMMY_MAIN' or # `AC_F77_MAIN' and `AC_FC_MAIN' are probably also necessary to link # C/C++ with Fortran; see below. # # and we would need libtool to create shared libraries. # Further, for any sensible test of the AC_F{77,C}(_DUMMY)?_MAIN macros # we also need to use AC_F{77,C}_WRAPPERS, in order to be able to actually # call the functions. ## ------------------------ ## ## AC_F77_DUMMY_MAIN usage. ## ## ------------------------ ## AT_SETUP([AC_F77_DUMMY_MAIN usage]) AT_CONFIGURE_AC([[ AC_PROG_F77 AC_F77_DUMMY_MAIN([], [AC_MSG_FAILURE([failed to determine F77 dummy main], [77])]) AC_F77_WRAPPERS AC_PROG_CC AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[ all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @F77@ @FFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[C This is just a purely numeric routine, no I/O needed. C Taken from autoconf.texi:Fortran Compiler. subroutine foobar (x, y) double precision x, y y = 3.14159 * x return end ]]) AT_DATA([cprogram.c], [[#include #include /* Taken from autoconf.texi:Fortran Compiler. */ #define FOOBAR_F77 F77_FUNC (foobar, FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_F77 (double *x, double *y); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN () { return 1; } #endif int main(int argc, char *argv[]) { double x = 2.7183, y; FOOBAR_F77 (&x, &y); if (fabs (8.539784097 - y) > 1.e-6) return 1; return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ F77_DUMMY_MAIN F77_FUNC F77_FUNC_ FC_DUMMY_MAIN_EQ_F77 ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram]) AT_CLEANUP ## ----------------------- ## ## AC_FC_DUMMY_MAIN usage. ## ## ----------------------- ## AT_SETUP([AC_FC_DUMMY_MAIN usage]) AT_CONFIGURE_AC([[ AC_PROG_FC AC_FC_FIXEDFORM AC_FC_DUMMY_MAIN([], [AC_MSG_FAILURE([failed to determine FC dummy main], [77])]) AC_FC_WRAPPERS AC_PROG_CC AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[ all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FCLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @FC@ @FCFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[C This is just a purely numeric routine, no I/O needed. C Taken from autoconf.texi:Fortran Compiler. subroutine foobar (x, y) double precision x, y y = 3.14159 * x return end ]]) AT_DATA([cprogram.c], [[#include #include /* Taken from autoconf.texi:Fortran Compiler. */ #define FOOBAR_FC FC_FUNC (foobar, FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_FC(double *x, double *y); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef FC_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int FC_DUMMY_MAIN () { return 1; } #endif int main (int argc, char *argv[]) { double x = 2.7183, y; FOOBAR_FC (&x, &y); if (fabs (8.539784097 - y) > 1.e-6) return 1; return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ FC_DUMMY_MAIN FC_DUMMY_MAIN_EQ_F77 FC_FUNC FC_FUNC_ ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram]) AT_CLEANUP ## ------------------ ## ## AC_F77_MAIN usage. ## ## ------------------ ## AT_SETUP([AC_F77_MAIN usage]) AT_CONFIGURE_AC([[ AC_PROG_F77 AC_F77_MAIN AC_F77_WRAPPERS AC_PROG_CC AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[ all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @F77@ @FFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[C This uses Fortran I/O, so is likely to require Fortran startup. subroutine foobar (x) integer x if (x == 42) then write(*,*) 'some output from Fortran sources' end if end ]]) AT_DATA([cprogram.c], [[#include #include /* Taken from autoconf.texi:Fortran Compiler. */ #define FOOBAR_F77 F77_FUNC (foobar, FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_F77 (int *x); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef __cplusplus extern "C" #endif int F77_MAIN (int argc, char *argv[]); int F77_MAIN (int argc, char *argv[]) { int x = 42; puts ("output from C main"); fflush (stdout); FOOBAR_F77 (&x); puts ("more output from C main"); return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ F77_DUMMY_MAIN F77_FUNC F77_FUNC_ F77_MAIN FC_DUMMY_MAIN_EQ_F77 ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram], [], [output from C main some output from Fortran sources more output from C main ]) AT_CLEANUP ## ----------------- ## ## AC_FC_MAIN usage. ## ## ----------------- ## AT_SETUP([AC_FC_MAIN usage]) AT_CONFIGURE_AC([[ AC_PROG_FC AC_FC_FIXEDFORM AC_FC_MAIN AC_FC_WRAPPERS AC_PROG_CC AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FCLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @FC@ @FCFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[C This uses Fortran I/O, so is likely to require Fortran startup. subroutine foobar (x) integer x if (x == 42) then write (*,*) 'some output from Fortran sources' end if end ]]) AT_DATA([cprogram.c], [[#include #include /* Taken from autoconf.texi:Fortran Compiler. */ #define FOOBAR_FC FC_FUNC (foobar, FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_FC (int *x); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef __cplusplus extern "C" #endif int FC_MAIN (int argc, char *argv[]); int FC_MAIN (int argc, char *argv[]) { int x = 42; puts ("output from C main"); fflush (stdout); FOOBAR_FC (&x); puts ("more output from C main"); return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ FC_DUMMY_MAIN FC_DUMMY_MAIN_EQ_F77 FC_FUNC FC_FUNC_ FC_MAIN ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram], [], [output from C main some output from Fortran sources more output from C main ]) AT_CLEANUP ## ------------------ ## ## AC_F77_FUNC usage. ## ## ------------------ ## AT_SETUP([AC_F77_FUNC usage]) AT_CONFIGURE_AC([[ AC_PROG_F77 AC_F77_FUNC([foobar]) AC_SUBST([foobar]) AC_PROG_CC AC_CONFIG_FILES([cprogram.c:cprogram.in]) AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[ all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @F77@ @FFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[ subroutine foobar (x) integer x x = 42 return end ]]) AT_DATA([cprogram.in], [[#include #include #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void @foobar@ (int *x); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN () { return 1; } #endif int main(int argc, char *argv[]) { int x; @foobar@ (&x); if (x != 42) return 1; return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ F77_DUMMY_MAIN FC_DUMMY_MAIN_EQ_F77 ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram]) AT_CLEANUP ## ----------------- ## ## AC_FC_FUNC usage. ## ## ----------------- ## AT_SETUP([AC_FC_FUNC usage]) AT_CONFIGURE_AC([[ AC_PROG_FC AC_FC_FUNC([foobar]) AC_SUBST([foobar]) AC_PROG_CC AC_CONFIG_FILES([cprogram.c:cprogram.in]) AC_CONFIG_FILES([Makefile]) ]]) AT_DATA([Makefile.in], [[ all: cprogram@EXEEXT@ cprogram@EXEEXT@: cprogram.@OBJEXT@ foobar.@OBJEXT@ @CC@ @CFLAGS@ @LDFLAGS@ -o $@ cprogram.@OBJEXT@ foobar.@OBJEXT@ @LIBS@ @FCLIBS@ .SUFFIXES: .c .f .@OBJEXT@ .f.@OBJEXT@: @FC@ @FCFLAGS@ -c $< .c.@OBJEXT@: @CC@ @DEFS@ -I. @CPPFLAGS@ @CFLAGS@ -c $< ]]) AT_DATA([foobar.f], [[ subroutine foobar (x) integer x x = 42 return end ]]) AT_DATA([cprogram.in], [[#include #include #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void @foobar@ (int *x); /* Taken from autoconf.texi:Fortran Compiler. */ #ifdef FC_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int FC_DUMMY_MAIN () { return 1; } #endif int main(int argc, char *argv[]) { int x; @foobar@ (&x); if (x != 42) return 1; return 0; } ]]) AT_CHECK_AUTOCONF AT_CHECK_AUTOHEADER([], [ FC_DUMMY_MAIN FC_DUMMY_MAIN_EQ_F77 ]) AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CHECK([./cprogram]) AT_CLEANUP ## ------------------- ## ## AC_FC_SRCEXT usage. ## ## ------------------- ## AT_SETUP([AC_FC_SRCEXT usage]) AT_DATA([configure.ac], [[AC_INIT AC_PROG_FC FCFLAGS_NOFREE=$FCFLAGS AC_SUBST([FCFLAGS_NOFREE]) AC_FC_FREEFORM # Unconditionally require .f to work. AC_FC_SRCEXT([f]) # For each other extension, fail gracefully if it does not work: # Not all compilers support all extensions/language versions. m4@&t@_foreach([ext], [f77, f90, f95, f03, f08], [AC_FC_SRCEXT(ext, ext[_object='foo]ext[.$(OBJEXT)'], ext[_object=]) AC_SUBST(ext[_object])]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT ]]) AT_DATA([Makefile.in], [[OBJEXT = @OBJEXT@ all: prog@EXEEXT@ prog@EXEEXT@: foof.@OBJEXT@ @f77_object@ @f90_object@ \ @f95_object@ @f03_object@ @f08_object@ @FC@ @FCFLAGS@ -o $@ foof.@OBJEXT@ @f77_object@ @f90_object@ \ @f95_object@ @f03_object@ @f08_object@ .SUFFIXES: .f .f77 .f90 .f95 .f03 .f08 .@OBJEXT@ .f.@OBJEXT@: @FC@ -c @FCFLAGS_NOFREE@ @FCFLAGS_f@ $< .f77.@OBJEXT@: @FC@ -c @FCFLAGS_NOFREE@ @FCFLAGS_f77@ $< .f90.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f90@ $< .f95.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f95@ $< .f03.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f03@ $< .f08.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f08@ $< ]]) AT_DATA([foof.f], [[ program main end ]]) AT_DATA([foof77.f77], [[ subroutine foof77 end ]]) AT_DATA([foof90.f90], [[subroutine foof90 end ]]) AT_DATA([foof95.f95], [[subroutine foof95 end ]]) AT_DATA([foof03.f03], [[subroutine foof03 end ]]) AT_DATA([foof08.f08], [[subroutine foof08 end ]]) AT_CHECK_AUTOCONF AT_CHECK_CONFIGURE AT_CHECK_MAKE AT_CLEANUP ## ---------------------- ## ## AC_FC_PP_SRCEXT usage. ## ## ---------------------- ## AT_SETUP([AC_FC_PP_SRCEXT usage]) AT_DATA([configure.ac], [[AC_INIT AC_PROG_FC # Unconditionally require .f and .F to work. AC_FC_PP_SRCEXT([f]) AC_FC_PP_SRCEXT([F]) # For each other extension, fail gracefully if it does not work: # Not all compilers support all extensions/language versions. m4@&t@_foreach([ext], [f77, f90, f95, f03, f08], [AC_FC_PP_SRCEXT(ext, ext[_object='foo]ext[.$(OBJEXT)'], ext[_object=]) AC_SUBST(ext[_object])]) m4@&t@_foreach([ext], [F77, F90, F95, F03, F08], [AC_FC_PP_SRCEXT(ext, ext[_object='bar]ext[.$(OBJEXT)'], ext[_object=]) AC_SUBST(ext[_object])]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT ]]) AT_DATA([Makefile.in], [[OBJEXT = @OBJEXT@ all: prog@EXEEXT@ prog@EXEEXT@: foof.@OBJEXT@ @f77_object@ @f90_object@ \ @f95_object@ @f03_object@ @f08_object@ \ barF.@OBJEXT@ @F77_object@ @F90_object@ \ @F95_object@ @F03_object@ @F08_object@ @FC@ @FCFLAGS@ -o $@ foof.@OBJEXT@ @f77_object@ @f90_object@ \ @f95_object@ @f03_object@ @f08_object@ \ barF.@OBJEXT@ @F77_object@ @F90_object@ \ @F95_object@ @F03_object@ @F08_object@ .SUFFIXES: .f .f77 .f90 .f95 .f03 .f08 .F .F77 .F90 .F95 .F03 .F08 .@OBJEXT@ .f.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f@ $< .f77.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f77@ $< .f90.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f90@ $< .f95.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f95@ $< .f03.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f03@ $< .f08.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_f08@ $< .F.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F@ $< .F77.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F77@ $< .F90.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F90@ $< .F95.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F95@ $< .F03.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F03@ $< .F08.@OBJEXT@: @FC@ -c @FCFLAGS@ @FCFLAGS_F08@ $< ]]) for ext in f77 f90 f95 f03 f08; do cat > foo$ext.$ext < bar$ext.$ext <configure.ac <prog.f <configure.ac <