? process.log.2 ? diff.out ? doc/diff.out Index: ChangeLog =================================================================== RCS file: /cvs/autoconf/ChangeLog,v retrieving revision 1.1466 diff -u -r1.1466 ChangeLog --- ChangeLog 2001/06/26 11:30:22 1.1466 +++ ChangeLog 2001/06/26 14:11:46 @@ -1,3 +1,21 @@ +2001-06-26 Steven G. Johnson + + Add alternate 'main' routine detection for linking C/C++ with Fortran, + fixing link failures for e.g. AC_F77_WRAPPERS on NetBSD. + + * aclang.m4 (AC_F77_DUMMY_MAIN): New macro to detect whether a + dummy alternate main is required even if the user provides her own + 'main'. + (AC_F77_MAIN): New macro to detect whether it is possible to + provide an alternate 'main' function name, using the 'main' from + the Fortran libraries. + (AC_LANG_PROGRAM(C)): Use F77_DUMMY_MAIN, if it is defined, so that + cross-language link tests can be performed successfully. + (_AC_F77_NAME_MANGLING): Require AC_F77_DUMMY_MAIN. Also put $FLIBS + after $LIBS, for consistency; this should be the general rule since + the user may want to link to Fortran libraries that require $FLIBS. + * autoconf.texi: Document AC_F77_DUMMY_MAIN and AC_F77_MAIN. + 2001-06-26 Akim Demaille Version 2.50a. Index: aclang.m4 =================================================================== RCS file: /cvs/autoconf/aclang.m4,v retrieving revision 1.137 diff -u -r1.137 aclang.m4 --- aclang.m4 2001/06/25 06:14:43 1.137 +++ aclang.m4 2001/06/26 14:11:46 @@ -356,6 +356,12 @@ # -------------------------------------- m4_define([AC_LANG_PROGRAM(C)], [$1 +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() { return 1; } +#endif int main () { @@ -1894,6 +1900,96 @@ AC_LANG_POP(Fortran 77)dnl ])# AC_F77_LIBRARY_LDFLAGS +# AC_F77_DUMMY_MAIN([ACTION-IF-FAIL], [ACTION-IF-NONE], [ACTION-IF-FOUND]) +# --------------------- +# Detect name of dummy main routine required by the Fortran libraries, +# (if any) and define F77_DUMMY_MAIN to this name (which should be +# used for a dummy declaration, if it is defined). On some systems, +# linking a C program to the Fortran library does not work unless you +# supply a dummy function called something like MAIN__. +# +# Execute ACTION-IF-FAIL if no way of successfully linking a C program +# with the F77 libs is found; default to exiting with an error message. +# Execute ACTION-IF-NONE if no dummy main is required for linking. +# Execute ACTION-IF-FOUND if a dummy routine name is found (default to +# defining F77_DUMMY_MAIN). +# +# What is technically happening is that the Fortran libraries provide +# their own main() function, which usually initializes Fortran I/O +# and similar stuff, and then calls MAIN__, which is the entry point +# of your program. Usually, a C program will override this with its +# own main() routine, but the linker sometimes complain if you don't +# provide a dummy (never-called) MAIN__ routine anyway. +# +# Of course, programs that want to allow Fortran subroutines to do +# I/O, etcetera, should call their main routine MAIN__() (or whatever) +# instead of main(). A separate autoconf test (AC_F77_MAIN) checks +# for the routine to use in this case (since the semantics of the +# test are slightly different). To link to e.g. purely numerical +# libraries, this is normally not necessary, however, and most C/C++ +# programs are reluctant to turn over so much control to Fortran. =) +# +# The name variants we check for are (in order): +# MAIN__ (g77, MAIN__ required on some systems; IRIX, MAIN__ optional) +# MAIN_, __main (SunOS) +# MAIN _MAIN __MAIN main_ main__ _main (we follow DDD and try these too) +# +AC_DEFUN([AC_F77_DUMMY_MAIN], +[AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])dnl +AC_CACHE_CHECK([for dummy main to link with Fortran 77 libraries], + ac_cv_f77_dummy_main, +[AC_LANG_PUSH(C)dnl + ac_save_LIBS=$LIBS + LIBS="$LIBS $FLIBS" + + # First, try linking without a dummy main: + AC_TRY_LINK([],[],ac_cv_f77_dummy_main=none,ac_cv_f77_dummy_main=unknown) + + if test $ac_cv_f77_dummy_main = unknown; then + for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do + AC_TRY_LINK_FUNC($ac_func, [ac_cv_f77_dummy_main=$ac_func; break]) + done + fi + LIBS=$ac_save_LIBS + AC_LANG_POP(C)dnl +]) +if test $ac_cv_f77_dummy_main = unknown; then + m4_default([$1],[AC_MSG_ERROR([Linking to Fortran libraries from C fails.])]) +elif test $ac_cv_f77_dummy_main = none; then + m4_default([$2],[:]) +else + m4_default([$3], + [AC_DEFINE_UNQUOTED([F77_DUMMY_MAIN], $ac_cv_f77_dummy_main, + [Define to dummy "main" function (if any) required to link to the Fortran 77 libraries.])]) +fi +])# AC_F77_DUMMY_MAIN + +# AC_F77_MAIN +# --------------------- +# Define F77_MAIN to name of alternate main() function for use with +# the Fortran libraries. (Typically, the libraries may define their +# own main() to initialize I/O, etcetera, that then call your own +# routine called MAIN__ or whatever.) See AC_F77_DUMMY_MAIN, above. +# If no such alternate name is found, just define F77_MAIN to main. +# +AC_DEFUN([AC_F77_MAIN], +[AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])dnl +AC_CACHE_CHECK([for alternate main to link with Fortran 77 libraries], + ac_cv_f77_main, +[AC_LANG_PUSH(C)dnl + ac_save_LIBS=$LIBS + LIBS="$LIBS $FLIBS" + ac_cv_f77_main="main" # default entry point name + + for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do + AC_TRY_LINK([#undef F77_DUMMY_MAIN +#define main $ac_func], [], [ac_cv_f77_main=$ac_func; break]) + done + LIBS=$ac_save_LIBS + AC_LANG_POP(C)dnl +]) +AC_DEFINE_UNQUOTED([F77_MAIN], $ac_cv_f77_main, [Define to alternate name for "main" routine that is called from a "main" in the Fortran libraries.]) +])# AC_F77_MAIN # _AC_F77_NAME_MANGLING # --------------------- @@ -1912,6 +2008,7 @@ # AC_DEFUN([_AC_F77_NAME_MANGLING], [AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])dnl +AC_REQUIRE([AC_F77_DUMMY_MAIN])dnl AC_CACHE_CHECK([for Fortran 77 name-mangling scheme], ac_cv_f77_mangling, [AC_LANG_PUSH(Fortran 77)dnl @@ -1927,7 +2024,7 @@ AC_LANG_PUSH(C)dnl ac_save_LIBS=$LIBS - LIBS="cf77_test.$ac_objext $FLIBS $LIBS" + LIBS="cf77_test.$ac_objext $LIBS $FLIBS" ac_success=no for ac_foobar in foobar FOOBAR; do Index: doc/autoconf.texi =================================================================== RCS file: /cvs/autoconf/doc/autoconf.texi,v retrieving revision 1.477 diff -u -r1.477 autoconf.texi --- doc/autoconf.texi 2001/06/23 22:59:11 1.477 +++ doc/autoconf.texi 2001/06/26 14:11:47 @@ -4670,6 +4670,69 @@ add these Fortran 77 libraries. Hence, the macro @code{AC_F77_LIBRARY_LDFLAGS} was created to determine these Fortran 77 libraries. + +The macro @code{AC_F77_DUMMY_MAIN} or @code{AC_F77_MAIN} will probably +also be necessary to link C/C++ with Fortran; see below. address@hidden defmac + address@hidden AC_F77_DUMMY_MAIN(@ovar{ACTION-IF-FAIL}, @ovar{ACTION-IF-NONE}, @ovar{ACTION-IF-FOUND}) address@hidden F77_DUMMY_MAIN address@hidden F77_DUMMY_MAIN +With many compilers, the Fortran libraries detected by address@hidden provide their own @code{main} entry +function that initializes things like Fortran I/O, and which then calls +a user-provided entry function named e.g. @code{MAIN__} to run the +user's program. The @code{AC_F77_DUMMY_MAIN} or @code{AC_F77_MAIN} +macros figure out how to deal with this interaction. + +When using Fortran only for purely numerical functions (no I/O, +etcetera), users often prefer to provide their own @code{main} and skip +the Fortran library initializations. In this case, however, one may +still need to provide a dummy @code{MAIN__} routine in order to prevent +linking errors on some systems. @code{AC_F77_DUMMY_MAIN} detects +whether any such routine is @emph{required} for linking, and what its +name is. + +If it cannot figure out how to link successfully, @code{ACTION-IF-FAIL} +is executed, with the default action being to exit with an error +message. @code{ACTION-IF-NONE} is executed if no dummy main is needed +(default: no action). @code{ACTION-IF-FOUND} is executed if a dummy +main is required; the default action is to define @code{F77_DUMMY_MAIN} +to the name of this required routine (e.g. @code{MAIN__}). + +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: + address@hidden +#ifdef F77_DUMMY_MAIN +# ifdef __cplusplus + extern "C" +# endif + int F77_DUMMY_MAIN() @{ return 1; @} +#endif address@hidden example + +Note that @code{AC_F77_DUMMY_MAIN} is called automatically from address@hidden; there is generally no need to call it explicitly +unless one wants to change the default actions. address@hidden defmac + address@hidden AC_F77_MAIN address@hidden F77_MAIN address@hidden F77_MAIN +As discussed above for @code{AC_F77_DUMMY_MAIN}, many Fortran libraries +allow you to provide an entry point called e.g. @code{MAIN__} instead of +the usual @code{main}, which is then called by a @code{main} function in +the Fortran libraries that initializes things like Fortran I/O. The address@hidden macro detects whether it is @emph{possible} to +utilize such an alternate main function, and defines @code{F77_MAIN} to +the name of the function. (If no alternate main function name is found, address@hidden is simply defined to @code{main}.) + +Thus, when calling Fortran routines from C that perform things like I/O, +one should use this macro and name the "main" function @code{F77_MAIN} +instead of @code{main}. @end defmac @defmac AC_F77_WRAPPERS