2

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.

Joe
  • 250
  • 3
  • 16

2 Answers2

3

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.

M. S. B.
  • 28,968
  • 2
  • 46
  • 73
  • This looks like a step in the right direction but now I have: ld: cannot find -lunwind. I looked up a stackoverflow thread about this (http://stackoverflow.com/questions/335928/ld-cannot-find-an-existing-library) but I'm confused because I never explicitly tried to call -lunwind myself.. – Joe Apr 22 '12 at 23:07
  • 1
    Guessing, maybe libunwind is needed for the traceback option? Try removing that option. Try finding where libunwind is on your system and adding that directory with a -L option on the link command. Did you include the cxxlib-icc and nofor_main options? – M. S. B. Apr 23 '12 at 00:30
  • More specifically, just for folks reading this later... I removed the traceback option and I no longer had the unwind error. – Joe Apr 23 '12 at 01:34
2

Compiling/linking fortran and C++ is quite do-able, but there are some details to work out. Intel helpfully has their documentation online: http://software.intel.com/en-us/articles/intel-fortran-composer-xe-documentation/

See the Intel Fortran Compiler User/Reference guide, in particular the section "Compiler Reference" / "Mixed Language Programming" / "Fortran/C Mixed-Language Programs". Also useful is the "Compiler Reference" / "Libraries" section.

In the end, you will need to include the a number of fortran static lib's in your link line, and you may have to redistribute some fortran run-time dlls with your application.

jeffrey_t_b
  • 1,779
  • 12
  • 18