Linking C, C++, and Fortran 77


When a compiler calls a linker, it automatically gives the options needed for the native language to the linker. But if you for example want to link a Fortran program using a C compiler, you have to specify the Fortran compilers run-time libraries (locations and names). To do this one has to locate the run-time libraries for the involved compilers. We will give a few examples of how to find them on Unix machines.

Note that some linker might have an option to include the proper runtime libraries. An example of this is the Silicon Graphics C++ compiler environment; using the CC command to link your objects, you can supply the option -lftn to the linker, and it will use the appropriate Fortran run-time libraries.


Digital UNIX

Example GNU cc and g++

You only have to link a simple C/C++ hello world program using the -v option. This will provide you with a lot of information, in particular in which directories the libraries are located and what libraries should be included during linking. Look for a line similar to (the string ‘ld’ below is the linker, it could have another name)

gcc case:

ld -G 8 -O1 -call_shared
/usr/lib/cmplrs/cc/crt0.o
-L/usr/local/lib/gcc-lib/alpha-dec-osf3.2/2.7.2
-L/usr/local/alpha-dec-osf3.2/lib -L/usr/lib/cmplrs/cc
-L/usr/local/lib jh.o -lgcc -lc -lgcc
g++ case:

ld -G 8 -O1 -call_shared
/usr/lib/cmplrs/cc/crt0.o
-L/usr/local/lib/gcc-lib/alpha-dec-osf3.2/2.7.2
-L/usr/local/alpha-dec-osf3.2/lib -L/usr/lib/cmplrs/cc
-L/usr/local/lib /tmp/ccaaynoa1.o -lg++ -lstdc++ -lm -lgcc -lc -lgcc
The -L options define where the compiler should look for run-time libraries, and the -l defines the libraries that should be included during linking.


Example Digital f77

You can do the same as above with a simple Fortran program. You should look for a similar line as above:

f77 case:
/usr/lib/cmplrs/cc/ld -g0 -O4 -call_shared /usr/lib/cmplrs/cc/crt0.o
/usr/lib/cmplrs/fort/for_main.o test.o -lUfor -lfor -lFutil -lm -lots
-lc

So far so good, so what?

Now that we know the names and locations of the run-time libraries, how do we use the information? Suppose that we have a C program that uses (and therefore has to be linked to) some Fortran code and that we want to use the C compiler to call the linker. This means that we have to explicitly link to the Fortran run-time libraries. This is most easily done using makefiles. We provide a sample makefile based on the information above.


Linux on an x86

Example gcc, g++ and g77

In this example we assume that we have a C++ program that uses Fortran code compiled with g77. We want to use g++ to call the linker and therefore we need to find the Fortran run-time libraries used by g77. As in the previous example we link a simple Fortran program using the -v option and look for a line similar to (the string ending with ‘ld’ below is the linker, it could have another ending such as ‘collect2’)

/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/ld -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/crtbegin.o
-L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29
-L/usr/i386-redhat-linux/lib /tmp/cca032621.o -lf2c -lm -lgcc -lc
-lgcc /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/crtend.o
/usr/lib/crtn.o
Since g77 is integrated with gcc we want to see what is specific to Fortran and therefore we link a simple C++ program in the same way looking for a line similar to (the string ending with ‘ld’ below is the linker, it could have another ending such as ‘collect2’)

/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/ld -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/crtbegin.o
-L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29
-L/usr/i386-redhat-linux/lib /tmp/cca032921.o -lstdc++ -lm -lgcc -lc
-lgcc /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.90.29/crtend.o
/usr/lib/crtn.o
By comparing the two we note that g77 only uses one Fortran run-time library: -lf2c. We further note that g77 and g++ looks for libraries in the same places, i.e. the -L options are the same in the two cases. We conclude, that we can use g++ to compile and link a C++ program, which calls Fortran code compiled with g77, provided we also link to the library -lf2c. It seems like the ecgs project (our ecgs version 2.91.66) changed the name of the f2c library to g2c. i.e. in this case change -lf2c to -lg2c.

Note: The GNU project is kind enough to specify in the g77 manual page that the Fortran run-time library is libf2c.a. However, the example above clarifies how the cross-linking can be done when less documented compilers are used.