Image by: Opensource.com CC-by-SA 4.0
When I was an undergraduate physics student in the early 1990s, the standard programming language for scientific programming was FORTRAN 77. Actually, Fortran 90 (with the new capitalization) had just been released around that time, but my university still used FORTRAN 77.
Every physics student in my program had to learn FORTRAN 77 to do their lab analysis. Not everything can be done in a spreadsheet; if you needed to discover the parameters of a damped pendulum, the best way to do that was to enter the data and run a numerical analysis where you can tweak the parameters until the simulation matches the data you collected. And while you could probably do that in C, it was much easier to do it using FORTRAN 77.
At university, I had a few accounts on the campus computer labs: the VAX lab where the FORTRAN compiler was installed, and the Unix lab where we had a C compiler. I also ran DOS at home, and dual-booted into Linux, but I only had a C compiler: Turbo C on DOS, and GCC on Linux. It would be years before GNU added gfortran to compile FORTRAN programs.
The only reason I had an account on the VAX was to write FORTRAN 77 programs. The systems administrator said it was too expensive to purchase a FORTRAN compiler for the Unix systems. If I wanted to work on FORTRAN programs for my lab analysis, I was stuck using the VAX.
That is, until I discovered an early open source program called f2c from Bell Labs. As the name might imply, f2c converted FORTRAN programs to C. You weren’t meant to maintain the generated C source files, it was an intermediate step to compile FORTRAN programs with just a C compiler. That meant I could finally compile FORTRAN 77 programs on my Linux system, using f2c to convert the original source and GCC to compile it into a program.
Exploring the past
I thought it would be fun to go back and explore f2c on modern Linux. While GNU has since released gfortran to compile new-style Fortran and old-style FORTRAN programs, I think it’s good to see what programming looked like in the early days of Linux.
Download both src.tgz and libf2c.zip from the f2c repository at Netlib, and extract them on your system. Note that src is a gzip-compressed tar file (tgz) and libf2c is a zip file. It doesn’t matter where you extract these; I unpacked them in the Downloads folder where I downloaded the files:
$ tar xzf src.tgz
$ unzip -q libf2c.zip -d libf2c
The zip file doesn’t contain a directory, so you need to tell the zip program where to put the files using the -d option. The extra -q option is to make the program run quietly; otherwise, unzip will print the filenames as they are extracted from the zip file.
The f2c library
Go into the libf2c directory, which is the source to the f2c library. The README file is usually where you learn how to compile a program. However, this README was written at a time when Linux was still quite “young,” so it has a few unnecessary steps to compile on a modern Linux system. These are the steps I used:
- Copy the
makefile.ufile toMakefile make hadd(this creates thef2c.hfile)make(this creates thelibf2c.alibrary)
The f2c program
Now go into the src directory, which has the source to the f2c program. Again, the README file here is a bit dated, and isn’t correct for a modern Linux system. Fortunately, compiling f2c requires just two steps:
- Copy the
makefile.ufile toMakefile make(this creates the f2c program)
Compiling a FORTRAN program
Let’s see how to compile a FORTRAN 77 using f2c, just like it was the early 1990s. FORTRAN 77 was a popular programming language for scientific computing because the language made it very easy to translate equations and other mathematical statements into computer code; the “FORTRAN” name is an abbreviation of formula translation.
FORTRAN 77 and earlier versions of the language used a strict column syntax: C or * in column 1 meant the line was a comment. Columns 1 to 5 were otherwise reserved for numbers, which were used as line labels. Almost any character in column 6 indicated a continuation line; this line was “glued” to the line before it. Program instructions went in columns 7 to 72; columns 73 and beyond were ignored.
With this basic understanding of FORTRAN’s columns, we can write a simple test program. This program prints the numbers 1 to 10, as double precision floating point values, plus the square root for each:
PROGRAM LOOP
DOUBLE PRECISION X
X=1D0
10 PRINT 99, X, DSQRT(X)
99 FORMAT(F6.3,' ',F6.3)
X = X + 1D0
IF (X.GT.10D0) GOTO 20
GOTO 10
20 END
I saved my sample program as loop.f in my Downloads folder, which has the libf2c and src directories for the f2c library and program. That makes it easy to reference the f2c program when I compile my test program, as well as the f2c.h header file and the libf2c.a library:
$ src/f2c loop.f
loop.f:
MAIN loop:
$ gcc -I./libf2c -L./libf2c -o loop loop.c -lf2c -lm
While not every program requires the m (math) library, it’s good practice to include -lm to link your FORTRAN 77 programs anyway. The math library won’t be used if it’s not needed, and it’s there for the programs that use certain functions like SQRT.
With these two commands, I’ve successfully compiled a FORTRAN 77 program using the f2c translator and the GCC compiler. The output prints the numbers from 1 to 10 and their square root:
$ ./loop
1.000 1.000
2.000 1.414
3.000 1.732
4.000 2.000
5.000 2.236
6.000 2.449
7.000 2.646
8.000 2.828
9.000 3.000
10.000 3.162
FORTRAN on early Linux
The f2c program made it possible to compile FORTRAN 77 programs on Linux, even though I didn’t actually have a FORTRAN 77 compiler. The f2c program converted the FORTRAN 77 code into C, which could be compiled using GCC, as long as you provided the f2c.h header file and libf2c.a library file. Compiling was always a two-step process: convert, then compile. But it was a simple series of steps that could be easily managed, either with a clever Makefile or Bash script.
If you don’t want to provide the path to the header file (with -I) or the path to the library file (with -L) then you can install the files into the systemwide directories. I don’t recommend installing them to /bin or /usr/include or /usr/lib, since those are best reserved for system-installed programs and libraries. Instead, put them under /usr/local, where you would usually expect to copy local programs and libraries. You can do that as root using the install command:
$ sudo install src/f2c /usr/local/bin/f2c
$ sudo install libf2c/f2c.h /usr/local/include/f2c.h
$ sudo install libf2c/libf2c.a /usr/local/lib/libf2c.a
With these files installed in the correct locations, and assuming you have /usr/local/bin in your PATH variable, you should be able to compile any FORTRAN 77 program without the extra paths:
$ f2c loop.f
loop.f:
MAIN loop:
$ gcc -o loop loop.c -lf2c -lm
$ ./loop
1.000 1.000
2.000 1.414
3.000 1.732
4.000 2.000
5.000 2.236
6.000 2.449
7.000 2.646
8.000 2.828
9.000 3.000
10.000 3.162
That’s how I compiled my FORTRAN 77 programs as an undergraduate student, from the comfort of my Linux system at home. Using f2c meant I could edit and run FORTRAN 77 programs using my own computer, which was usually faster than the VAX system because I was the only person using it. That was a huge step forward for Linux to run like the Big Unix systems, without buying an expensive FORTRAN 77 compiler. That’s the power of open source, and one more reason that Linux continued to impress me in those early days.