Where has g77 gone to?

.... or : libg2c considered harmful

For various historical reasons, g77 has been declared obsolete, and has been replaced by gfortran. This page is intended to help those making the transition, and those who have been handed third-party software of considerable antiquity.

There is also a related run-time library problem: programs whose object-code intermediate files have been built with g77 may be linked using gcc, but will demand the library libg2c, both at link time and at runtime.

The official GNU position is that if any Fortran-77-conformant program compiles with g77 but fails with gfortran, that counts as a bug in gfortran. You may however need to add or change some compilation arguments, and possibly one or two of the link-time libraries.

Please try the following suggestions, which are presented in order of increasing ugliness, in the order given; stop with the first one which succeeds. You may be pleasantly surprised.

Full recompilation:

If you previously used a compilation line of the form:

g77 -o foo foo.f bar.f baz.f

.... the first thing to try would be:

gfortran -o foo foo.f bar.f baz.f

Under Snow Leopard and later, this will produce a 64-bit executable. The equivalent change in a Makefile would be

# From:
# FC=g77
# .... to:
FC=gfortran

.... and say make clean to clear out existing object-code files. Please see also the aside on Makefiles for more information.

If you've got a Makefile full of hard-coded g77 statements, please see the aside on Activate fake-g77 for a quick-and-dirty way to deal with that.

Full compilation, using gcc at link time:

Some suites mix sourcecode in Fortran and C. Even if you manage to get the names to line up properly (please see the Aside on mixing C and Fortran), getting the resultant object-code files to link together into a single executable isn't always easy, and the fine details of doing so tend to be compiler-suite-dependent. This is especially confusing to those who wish to link their C programs to a precompiled library written in Fortran, of which the standard example is cpgplot, which is a set of C bindings for PGPLOT.

The recommended way to Do The Right Thing when using GNU compilers is to use:

gfortran [ .... ]

.... to do the linkage. This replaces replaces the historically-venerated kludge:

cc [ .... ] -lm # BROKEN

.... which is no longer sufficiently equivalent, or something of the form:

g++ [ .... ] -lg2c # BROKEN

.... which is seen sometimes in sourcecode imported from Linux. Anybody who uses:

g++ [ .... ] -lgfortran # DEPRECATED

.... will be assumed to know what they're doing, and to be willing and able to cope with the consequences.

Background: The underlying problem is that Fortran is a larger language internally than C (libraries are a different matter). To provide some of the internal Fortran functions, Fortran compilers use extra libraries, over and above the standard C set; g77 used libg2c, for historical reasons, while gfortran uses libgfortran instead. Were we to compile (say) foo.c with gcc, and bar.f (or the library containing it) with g77, and then use gcc foo.o bar.o to do the linking, we would need to add the argument -lg2c to the linking command, and make libg2c available at run time.

So don't do that. If you compile with the Fortran compiler, use the same Fortran compiler to do the linking: it already knows which Fortran-specific libraries it needs, and will add them in without you even needing to know what they are, or where to put them in the library sequence. For example:

gcc foo.c
gfortran bar.f
gfortran -o fooprog foo.o bar.o

It's worth noting that gcc and gfortran share the same back-end software to do most of the compilation process, and that the manual page for gfortran contains only those options which it doesn't share with gcc. Think of gfortran as a wrapper around gcc which educates it about Fortran.

Full compilation, 32-bit:

If for some reason your program really does need to be 32-bit, the next thing to try would be:

gfortran -m32 -o foo32 foo.f bar.f baz.f

If this is the case, we strongly recommend you test this directly, by also doing:

gfortran -m64 -o foo64 foo.f bar.f baz.f

.... and comparing the results.

If there's any differences in the results larger than can be accounted for by rounding errors, please let us know at the usual e-mail address. This would constitute a bug somewhere-or-other, and we will need to get to the bottom of it (either to fix it once and for all, or to document the problem and its workarounds) on everybody's behalf.

32-bit compilation with g77 object code:

One of the main reasons for wishing 32-bit compilation is to use pre-existing 32-bit libraries. If that's so, and said libraries were built using g77 (not always the case), you may need to change certain other gfortran settings. Please note:

  • From this point on, you are quite definitely into on your own head be it territory.

  • The proper fix is to find versions of the offending libraries which have been, or can be, compiled using gfortran with the default settings (including 64-bit object code).

    • In particular, the Starlink libraries under the current Astrophysics setup were built with HPC's gfortran and/or the system gcc, and are only being made available in 64-bit versions.

  • See the section in man gfortran dealing with the -ff2c option for quite what that option does, and for two important caveats which explain why this option shouldn't be used.

Library dependencies:

.... However, libraries built with g77 are likely to depend on dynamic libraries provided with g77, an unfortunate fact which often only turns up at run time. If the above 32-bit compilation succeeds for you, but the executable complains about missing system-type libraries, try installing g77 from Self-Service, then rerunning said executable without recompiling it.

Please note: this is the sort of kludgearound which is often advocated on the Net, which looks reasonable on the face of it, but which can easily curdle a system beyond all redemption. Such advice is more properly classified as being (in the words of HL Mencken) "simple, neat, obvious, and wrong". The wise user will instead invest the time to discover how to Do The Right Thing (in this case, finding versions of the offending libraries which have been, or can be, built with gfortran).

If all else fails:

.... it may still be possible to install g77 from OS X Self-Service, but please note:

  • This is entirely unsupported, even if it is still available, and should only be used in cases of utter desperation.
  • We cannot rule out the possibility that installing g77 on a system may destabilise it. The only viable fix for this sort of problem is to wipe the system partition, and reinstall the operating system from scratch.

Asides

Command-line flags:

  • 64-bit, generic:
        -m64
  • 32-bit, generic:
        -m32
  • 32-bit, Apple-specific:
        -arch i386
  • Contraindicated [Tony Lynas-Gray, pri comm]:
        -ff2c

The second and third are effectively equivalent. If in doubt, use the generic version: the -arch option is only available on Apple's gcc, and on AT&T's Apple-flavoured build of gfortran which is in use in Teaching. You only need to worry about the difference if you're building a "fat binary" (32-bit and 64-bit in the same executable), which now ought to only be necessary if you intend to run your code unchanged on Apple hardware which is no longer supported by in-warranty versions of MacOS X.

Makefiles:

The relevant variables in Makefiles include:

  • Fortran compiler:
        FC
  • Fortran77 compiler, which defaults to $(FC):
        F77
  • Flags to Fortran compiler:
        FFLAGS
  • Name of C compiler:
        CC
  • Flags to C compiler:
        CFLAGS
  • C preprocessor flags:
        CPPFLAGS
  • Loader flags (for libraries etc):
        LDFLAGS

Activate fake-g77:

Astrophysics only: If you've got a literal "g77" string hard-wired into more action lines than you've had hot dinners, or it's somebody else's Makefile which you can't tinker with, one quick-and-dirty way around this is to first say:

Activate fake-g77
make clean  # Precautionary

at your command line: this puts a shell script called g77 on your $PATH, which passes its command-line arguments straight through to gfortran. This was originally produced to help out a user in exactly this position, who was unable to change her Makefiles because she was using a source tree shared with an offsite collaborator.

Mixing C and Fortran:

Part of the reason for the transition from g77 to gfortran is to make mixing-in with C code simpler, and avoid (most of) the acts of cruel and unusual programming which were previously required to get the compilers' outputs to co-operate. Inevitably, the results of said acts were almost inevitably fragile and non-portable.

Please bring us examples. We're willing to put in the effort, and to then document the offending practices, together with our suggested replacements, for others to benefit from.

Categories: AOPP | Apple | Astrophysics | Development | Fortran | Historical | Linux | Mac | OS X | Theory