[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Linking C and Fortran code: problems with Compaq compilers
From: |
Steven G. Johnson |
Subject: |
Linking C and Fortran code: problems with Compaq compilers |
Date: |
Fri, 17 Aug 2001 22:31:25 -0400 (EDT) |
When linking a program that contains both C and Fortran source files,
automake uses the Fortran linker. This causes some difficulty with the
Compaq compilers ('fort' and 'ccc') for Alpha (Linux). Consider:
int main(int argc, char **argv) {
printf("Hello world.\n");
return 0;
}
If we compile this with ccc -c and then link with fort, we get:
/usr/lib/compaq/cfal/for_main.o: In function `main':
/usr/lib/compaq/cfal/for_main.o(.text+0x0): multiple definition of `main'
foo.o(.text+0x0): first defined here
/usr/lib/compaq/cfal/for_main.o: In function `main':
/usr/lib/compaq/cfal/for_main.o(.text+0x30): undefined reference to `MAIN__'
/usr/lib/compaq/cfal/for_main.o(.text+0x34): undefined reference to `MAIN__'
/usr/lib/compaq/cfal/for_main.o(.text+0x34): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
fort: Severe: Failed while trying to link.
The business about MAIN__ is common with many Fortran libraries. There
are two common solutions:
1) Rename 'main' to 'MAIN__', which lets the Fortran library use its own
main() as the program entry point, and then hand off control to your
MAIN__ after it's initialized anything it needs (typically, Fortran
I/O). (See the AC_F77_MAIN macro in autoconf 2.52.) This works here.
2) Often, the Fortran library initialization is not needed (e.g. you are
calling purely numerical routines), and the programmer doesn't wish to
hand off control to the Fortran library. So, you define your own 'main',
and possibly define a dummy MAIN__ routine to forestall linker errors:
int MAIN__(int argc, char **argv) { abort(); return 1; }
This is a common idiom that one sees in a number of codes (GNU R, GNU
Octave, Algae, Tela). (See the AC_F77_DUMMY_MAIN macro.) However, it
doesn't work if you use the Compaq Fortran linker; you get:
/usr/lib/compaq/cfal/for_main.o: In function `main':
/usr/lib/compaq/cfal/for_main.o(.text+0x0): multiple definition of `main'
What is the right thing to do?
1) Have automake default to the C linker, with the $(FLIBS) detected by
autoconf. This works on all the machines I've tried (it is possible to
force automake to do this by a various tricks), and typically allows you
to use (1) or (2) (neither is needed here).
But, you run the risk of FLIBS being incorrectly detected (e.g.
I'm told there is a bug in FLIBS detection on HP/UX). (C++ code has to use
the C++ linker and rely on FLIBS anyway.)
2) Recommend that C programmers use solution (1) with automake (but not
C++ programmers?). AC_F77_MAIN tries to detect the name (e.g. MAIN__)
that is used (if any), but you perhaps run the risk of the Fortran library
initializing something you don't want, or MAIN__ not being called in the
way you expect on some future system.
3) For the specific case of the Compaq Alpha compiler, there is a flag
-nofor_main that causes the Fortran main() routine to be omitted from the
library, in which case the original "Hello world" program works.
Steven
- Linking C and Fortran code: problems with Compaq compilers,
Steven G. Johnson <=