Subject: Re: Fortran 77 name-mangling scheme
To: Patrick Welche <prlw1@newn.cam.ac.uk>
From: Jason Beegan <jtb@netbsd.org>
List: tech-userlevel
Date: 05/24/2001 21:13:14
>
> autoconf's "checking for Fortran 77 name-mangling scheme" always fails. It
> seems it just tries to compile a fortran and C source file together like eg:
>
> conftest.f:
> subroutine foobar()
> return
> end
>
> conftest.c:
> char foobar();
>
> int main ()
> {
> foobar (); /* call the fortran subroutine */
>
> return 0;
> }
>
> quartz% gcc -c -o cc_test.o conftest.c
> quartz% gcc -c -o cf77_test.o conftest.f
> quartz% nm -g cc_test.o
> U foobar
> 00000000 T main
> quartz% nm -g cf77_test.o
> 00000000 T foobar_
>
>
> The above is on i386, elf. I take it this is meant to happen, but why?
>
> Then leads to the obvious:
> quartz% gcc -o conftest -g -O2 cc_test.o cf77_test.o -lg2c -lm
> /usr/lib/libg2c.so: warning: tempnam() possibly used unsafely, use mkstemp()
> or mkdtemp()
> cc_test.o: In function `main':
> cc_test.o(.text+0x4): undefined reference to `foobar'
> /usr/lib/libg2c.so: undefined reference to `MAIN__'
> collect2: ld returned 1 exit status
>
>
> s/foobar/foobar_/g in the .c file just gets the MAIN__ error - any thoughts
> on that one?
>
> Cheers,
>
> Patrick
>
MAIN__ is the Fortran equivalent of the C main() function. Since
you're calling Fortran from C, MAIN__ doesn't get used, hence the
error in linking.
The workaround is to put a dummy MAIN__ function into your C program.
It can be practically any function, but I always use
void
MAIN__(void)
{
abort();
}
You can also use the -u option of the C compiler
gcc -u MAIN__ -c -o cf77_test.o conftest.f
But the former is better (I think) because g77 doesn't have a -u
option so you can use the former regardless of whether you use g77 or
gcc for to do the linking.
If you look around pkgsrc/math you'll see a number of the packages
have these things already done for them. (In fact all of them that
mix Fortran and C have).
By the way, g77 and f2c always mangle their symbols by converting the
names to lower case and appending an underscore. So foobar_() is the
correct way to call the Fortran function foobar from C.
-- Jason Beegan