Previous: Erlang Compiler and Interpreter, Up: Compilers and Preprocessors
The Autoconf Fortran support is divided into two categories: legacy
Fortran 77 macros (F77
), and modern Fortran macros (FC
).
The former are intended for traditional Fortran 77 code, and have output
variables like F77
, FFLAGS
, and FLIBS
. The latter
are for newer programs that can (or must) compile under the newer
Fortran standards, and have output variables like FC
,
FCFLAGS
, and FCLIBS
.
Except for two new macros AC_FC_SRCEXT
and
AC_FC_FREEFORM
(see below), the FC
and F77
macros
behave almost identically, and so they are documented together in this
section.
Determine a Fortran 77 compiler to use. If
F77
is not already set in the environment, then check forg77
andf77
, and then some other names. Set the output variableF77
to the name of the compiler found.This macro may, however, be invoked with an optional first argument which, if specified, must be a blank-separated list of Fortran 77 compilers to search for. This just gives the user an opportunity to specify an alternative search list for the Fortran 77 compiler. For example, if you didn't like the default order, then you could invoke
AC_PROG_F77
like this:AC_PROG_F77([fl32 f77 fort77 xlf g77 f90 xlf90])If using
g77
(the GNU Fortran 77 compiler), then set the shell variableG77
to ‘yes’. If the output variableFFLAGS
was not already set in the environment, then set it to -g -02 forg77
(or -O2 whereg77
does not accept -g). Otherwise, setFFLAGS
to -g for all other Fortran 77 compilers.
Determine a Fortran compiler to use. If
FC
is not already set in the environment, thendialect
is a hint to indicate what Fortran dialect to search for; the default is to search for the newest available dialect. Set the output variableFC
to the name of the compiler found.By default, newer dialects are preferred over older dialects, but if
dialect
is specified then older dialects are preferred starting with the specified dialect.dialect
can currently be one of Fortran 77, Fortran 90, or Fortran 95. However, this is only a hint of which compiler name to prefer (e.g.,f90
orf95
), and no attempt is made to guarantee that a particular language standard is actually supported. Thus, it is preferable that you avoid thedialect
option, and use AC_PROG_FC only for code compatible with the latest Fortran standard.This macro may, alternatively, be invoked with an optional first argument which, if specified, must be a blank-separated list of Fortran compilers to search for, just as in
AC_PROG_F77
.If the output variable
FCFLAGS
was not already set in the environment, then set it to -g -02 for GNUg77
(or -O2 whereg77
does not accept -g). Otherwise, setFCFLAGS
to -g for all other Fortran compilers.
Test whether the Fortran compiler accepts the options -c and -o simultaneously, and define
F77_NO_MINUS_C_MINUS_O
orFC_NO_MINUS_C_MINUS_O
, respectively, if it does not.
The following macros check for Fortran compiler characteristics.
To check for characteristics not listed here, use
AC_COMPILE_IFELSE
(see Running the Compiler) or
AC_RUN_IFELSE
(see Runtime), making sure to first set the
current language to Fortran 77 or Fortran via AC_LANG([Fortran 77])
or AC_LANG(Fortran)
(see Language Choice).
Determine the linker flags (e.g., -L and -l) for the Fortran intrinsic and runtime libraries that are required to successfully link a Fortran program or shared library. The output variable
FLIBS
orFCLIBS
is set to these flags (which should be included afterLIBS
when linking).This macro is intended to be used in those situations when it is necessary to mix, e.g., C++ and Fortran source code in a single program or shared library (see Mixing Fortran 77 With C and C++).
For example, if object files from a C++ and Fortran compiler must be linked together, then the C++ compiler/linker must be used for linking (since special C++-ish things need to happen at link time like calling global constructors, instantiating templates, enabling exception support, etc.).
However, the Fortran intrinsic and runtime libraries must be linked in as well, but the C++ compiler/linker doesn't know by default how to add these Fortran 77 libraries. Hence, this macro was created to determine these Fortran libraries.
The macros
AC_F77_DUMMY_MAIN
andAC_FC_DUMMY_MAIN
orAC_F77_MAIN
andAC_FC_MAIN
are probably also necessary to link C/C++ with Fortran; see below.
With many compilers, the Fortran libraries detected by
AC_F77_LIBRARY_LDFLAGS
orAC_FC_LIBRARY_LDFLAGS
provide their ownmain
entry function that initializes things like Fortran I/O, and which then calls a user-provided entry function named (say)MAIN__
to run the user's program. TheAC_F77_DUMMY_MAIN
andAC_FC_DUMMY_MAIN
orAC_F77_MAIN
andAC_FC_MAIN
macros figure out how to deal with this interaction.When using Fortran for purely numerical functions (no I/O, etc.) often one prefers to provide one's own
main
and skip the Fortran library initializations. In this case, however, one may still need to provide a dummyMAIN__
routine in order to prevent linking errors on some systems.AC_F77_DUMMY_MAIN
orAC_FC_DUMMY_MAIN
detects whether any such routine is required for linking, and what its name is; the shell variableF77_DUMMY_MAIN
orFC_DUMMY_MAIN
holds this name,unknown
when no solution was found, andnone
when no such dummy main is needed.By default, action-if-found defines
F77_DUMMY_MAIN
orFC_DUMMY_MAIN
to the name of this routine (e.g.,MAIN__
) if it is required. action-if-not-found defaults to exiting with an error.In order to link with Fortran routines, the user's C/C++ program should then include the following code to define the dummy main if it is needed:
#ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif(Replace
F77
withFC
for Fortran instead of Fortran 77.)Note that this macro is called automatically from
AC_F77_WRAPPERS
orAC_FC_WRAPPERS
; there is generally no need to call it explicitly unless one wants to change the default actions.
As discussed above, many Fortran libraries allow you to provide an entry point called (say)
MAIN__
instead of the usualmain
, which is then called by amain
function in the Fortran libraries that initializes things like Fortran I/O. TheAC_F77_MAIN
andAC_FC_MAIN
macros detect whether it is possible to utilize such an alternate main function, and definesF77_MAIN
andFC_MAIN
to the name of the function. (If no alternate main function name is found,F77_MAIN
andFC_MAIN
are simply defined tomain
.)Thus, when calling Fortran routines from C that perform things like I/O, one should use this macro and name the "main" function
F77_MAIN
orFC_MAIN
instead ofmain
.
Defines C macros
F77_FUNC (name, NAME)
,FC_FUNC (name, NAME)
,F77_FUNC_(name, NAME)
, andFC_FUNC_(name, NAME)
to properly mangle the names of C/C++ identifiers, and identifiers with underscores, respectively, so that they match the name-mangling scheme used by the Fortran compiler.Fortran is case-insensitive, and in order to achieve this the Fortran compiler converts all identifiers into a canonical case and format. To call a Fortran subroutine from C or to write a C function that is callable from Fortran, the C program must explicitly use identifiers in the format expected by the Fortran compiler. In order to do this, one simply wraps all C identifiers in one of the macros provided by
AC_F77_WRAPPERS
orAC_FC_WRAPPERS
. For example, suppose you have the following Fortran 77 subroutine:subroutine foobar (x, y) double precision x, y y = 3.14159 * x return endYou would then declare its prototype in C or C++ as:
#define FOOBAR_F77 F77_FUNC (foobar, FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_F77(double *x, double *y);Note that we pass both the lowercase and uppercase versions of the function name to
F77_FUNC
so that it can select the right one. Note also that all parameters to Fortran 77 routines are passed as pointers (see Mixing Fortran 77 With C and C++).(Replace
F77
withFC
for Fortran instead of Fortran 77.)Although Autoconf tries to be intelligent about detecting the name-mangling scheme of the Fortran compiler, there may be Fortran compilers that it doesn't support yet. In this case, the above code generates a compile-time error, but some other behavior (e.g., disabling Fortran-related features) can be induced by checking whether
F77_FUNC
orFC_FUNC
is defined.Now, to call that routine from a C program, we would do something like:
{ double x = 2.7183, y; FOOBAR_F77 (&x, &y); }If the Fortran identifier contains an underscore (e.g.,
foo_bar
), you should useF77_FUNC_
orFC_FUNC_
instead ofF77_FUNC
orFC_FUNC
(with the same arguments). This is because some Fortran compilers mangle names differently if they contain an underscore.
Given an identifier name, set the shell variable shellvar to hold the mangled version name according to the rules of the Fortran linker (see also
AC_F77_WRAPPERS
orAC_FC_WRAPPERS
). shellvar is optional; if it is not supplied, the shell variable is simply name. The purpose of this macro is to give the caller a way to access the name-mangling information other than through the C preprocessor as above, for example, to call Fortran routines from some language other than C/C++.
By default, the
FC
macros perform their tests using a .f extension for source-code files. Some compilers, however, only enable newer language features for appropriately named files, e.g., Fortran 90 features only for .f90 files. On the other hand, some other compilers expect all source files to end in .f and require special flags to support other file name extensions. TheAC_FC_SRCEXT
macro deals with both of these issues.The
AC_FC_SRCEXT
tries to get theFC
compiler to accept files ending with the extension .ext (i.e., ext does not contain the dot). If any special compiler flags are needed for this, it stores them in the output variableFCFLAGS_
ext. This extension and these flags are then used for all subsequentFC
tests (untilAC_FC_SRCEXT
is called again).For example, you would use
AC_FC_SRCEXT(f90)
to employ the .f90 extension in future tests, and it would set aFCFLAGS_f90
output variable with any extra flags that are needed to compile such files.The
FCFLAGS_
ext can not be simply absorbed intoFCFLAGS
, for two reasons based on the limitations of some compilers. First, only oneFCFLAGS_
ext can be used at a time, so files with different extensions must be compiled separately. Second,FCFLAGS_
ext must appear immediately before the source-code file name when compiling. So, continuing the example above, you might compile a foo.f90 file in your makefile with the command:foo.o: foo.f90 $(FC) -c $(FCFLAGS) $(FCFLAGS_f90) '$(srcdir)/foo.f90'If
AC_FC_SRCEXT
succeeds in compiling files with the ext extension, it calls action-if-success (defaults to nothing). If it fails, and cannot find a way to make theFC
compiler accept such files, it calls action-if-failure (defaults to exiting with an error message).
The
AC_FC_FREEFORM
tries to ensure that the Fortran compiler ($FC
) allows free-format source code (as opposed to the older fixed-format style from Fortran 77). If necessary, it may add some additional flags toFCFLAGS
.This macro is most important if you are using the default .f extension, since many compilers interpret this extension as indicating fixed-format source unless an additional flag is supplied. If you specify a different extension with
AC_FC_SRCEXT
, such as .f90 or .f95, thenAC_FC_FREEFORM
ordinarily succeeds without modifyingFCFLAGS
.If
AC_FC_FREEFORM
succeeds in compiling free-form source, it calls action-if-success (defaults to nothing). If it fails, it calls action-if-failure (defaults to exiting with an error message).