Multiple definition of main: linking fortran with C++
I would like to write a C++ program that calls the mvndst_() subroutine from
http://www.math.wsu.edu/faculty/genz/software/fort77/mvndstpack.f
On Linux, if I create test.cc:
extern "C" {
int mvndst_(int *, double *, double *, int *, double *, int *,
double *, double *, double *, double *, int *);
};
int main() {
return 0;
}
and compile via
g++ -c -o test.o test.cc
gfortran -c -o mvndstpack.o mvndstpack.f
gfortran -Mnomain -o test test.o mvndstpack.o
then I get
mvndstpack.o: In function `main':
mvndstpack.f:(.text+0x4a2a): multiple definition of `main'
test.o:test.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status
However, if I run strip -N main mvndstpack.o
prior to linking, then the linking succeeds. Can someone explain why the -Mnomain flag did not work here? I'd also like to avoid a solution that uses "strip" since the behavior of "strip" on Mac OS X appears to be different (i.e., the -N option is not available, and I'm not sure of another way to obtain the right behavior). I'd also like to avoid editing the original Fortran source, if possible.
Details: - GNU Fortran (Ubuntu/Linaro 4.6开发者_C百科.1-9ubuntu3) 4.6.1 - g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 - GNU strip (GNU Binutils for Ubuntu) 2.21.53.20110810 - strip on Mac OS X 10.6 Snow Leopard
I can't find any documentation for the -Mnomain
option, but gfortran
doesn't complain about it (it seems to pass it on to the linker). But it also didn't complain when I ran
gfortran -Mnoplatypus -o test test.o mvndstpack.o
So my guess is that it doesn't support -Mnomain
, and that it's being silently ignored. (Either that, or there's a -Mnoplatypus
option, but that hardly seems likely.)
What worked for me was to comment out the PROGRAM TSTNRM
.. END
lines in mvndstpack.f
(lines 15 through 62).
That's probably the most sensible approach anyway; you don't want to use the Fortran main program, so you might as well not compile it, rather than trying to trick the linker into ignoring it.
(If you prefer, you can use #if ... #endif
or #ifdef ... #endif
.)
EDIT:
Since your main program is in C++, you probably need to use g++
, not gfortran
, to create the executable:
g++ -c -o test.o test.cc
gfortran -c -o mvndstpack.o mvndstpack.f
g++ -o test test.o mvndstpack.o
(And at some point you'll actually want to call the function.)
Your problem is the FORTRAN code you have includes a main
as well, just in that world it is known as PROGRAM
. From mvndstpack.f:
PROGRAM TSTNRM
*
* Test program for MVNDST
*
You need to pick which side of the fence is going to host the party first!
In this case you want the C++ to call the FORTRAN, therefore you just need to ditch the top part of the FORTRAN file which contains the TSTNRM
program, or wrap it in a conditional compilation section:
#if TEST
PROGRAM TSTNRM
...
END
#endif
You can then rename the file to (case matters) mvndstpack.F
or mvndstpack.FPP
, or use -cpp
on the command line options to gfortran.
精彩评论