Call the Fortran subroutine from C ++ using Intel compilers

advertisements

I need to call a Fortran program within a C++ code. The program is compiled using an Intel compiler The Fortran program spans several files, and used to be called as a PROGRAM. What I tried to do was change the main PROGRAM call to a SUBROUTINE called SIMULATOR. Then, I compiled each Fortran source code into an object file without putting them all into an executable. I then got ready to link all the Fortran objects up with a simple C++ wrapper for testing. The code and makefile follow.

wrapper.cpp:

#include <iostream.h>

using namespace std;

extern "C"{
void simulator_();
}

int main()
{
    cout << "starting..." << endl;
    simulator_();
    cout << "success!" << endl;
    return 0;
}

Makefile:

all:
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c modules.for
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c Finterp.for
--a few more sources go here--
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c Simsys.for
    icpc -c wrapper.cpp
    icpc -o cppprogram *.o

Here is (part of) the output from the compiler. Simsys is the file that contains the simulator function I'm trying to call:

Simsys.o: In function `simsys_':
Simsys.for:(.text+0xed4): undefined reference to `for_write_int_lis'
Simsys.for:(.text+0xeef): undefined reference to `for_adjustl'
Simsys.for:(.text+0xf38): undefined reference to `for_trim'
Simsys.for:(.text+0xf83): undefined reference to `for_concat'
Simsys.for:(.text+0x1071): undefined reference to `for_open'
Simsys.for:(.text+0x131d): undefined reference to `for_emit_diagnostic'
Simsys.o:Simsys.for:(.text+0x1670): more undefined references to `for_emit_diagnostic' follow

Now according to a person with a similar problem (http://www.velocityreviews.com/forums/t288905-intel-compiler-8-1-c-calling-fortran-routine.html), it seems like I'm missing some libraries. That person wrote that they included a specific library and it helped them, but I don't know how to begin to look for what libraries I need. I also don't know how to find the path of the intel compiler on the HPC system I'm using, so I would appreciate some help looking in the right direction. I didn't have to do anything special to compile the fortran PROGRAM before I was trying to link it with the C++, so I'm kind of stuck in thinking about where to go from here.

By the way, the Fortran program doesn't need any inputs, it's all self-contained.

Thanks in advance for your help and insights!

Edits:

which ifort gave me: /usr/global/intel/Compiler/11.1/073/bin/intel64/ifort

After trying to do the final link using ifort, I got the following error:

ld: cannot find -lunwind

I found documentation about unwind (https://savannah.nongnu.org/news/?group=libunwind) but I didn't try to call this library myself and don't know where this was coming from.


The easy way is to use ifort for the linking, to obtain the Fortran runtime libraries. Some instructions are at http://www.ualberta.ca/AICT/RESEARCH/LinuxClusters/doc/ifc91/main_for/mergedProjects/bldaps_for/pgsclmix.htm

If you use the ISO_C_Binding on the Fortran side you can take control of the name of the routine and get rid of the underscore. Trivial ... the ISO C Binding will become much more useful if you start adding arguments between C/C++ and Fortran.