title: Linking legacy Fortran95 library to C++ with ifort/icpc
body: <p><strong>Background:</strong> I am in a situation where I have to make use of an old Fortran95 library in a new C++ project. The F95 library is extensive, has tons of small modules, poorly documented, and it was mostly auto-generated about a decade ago by some obscure computer algebra system (by people on a different continent). So basically heirloom code, but it works and it is currently irreplaceable.</p>
  
  <p>Luckily I have the source code and it can be compiled with current versions of ifort, but I am not too familiar with Fortran, and would rather not touch the old code in any significant way.</p>
  
  <p>So suppose I have this Fortran code (pes_shell.f90):</p>
  
  <pre><code>subroutine pes_init()
    use pes,wp=&gt;pes_wp
    implicit none
    real,parameter::auang=0.5291772083
    call pes0_init (dir='coef')
    call pes1_init (pes_x3y1z1u1_sysall)
  return
  end subroutine pes_init
  </code></pre>
  
  <p>The functions pes0_init(...) and pes1_init(...) lead into the abyssal depths of the Fortran library and they are contained in the pes module.</p>
  
  <p>I can compile this to an object file, if I give ifort the path for the modules:</p>
  
  <pre><code>ifort -r8 -O2 -c pes_shell.f90 -I/home/debianuser/PES/PES_library/lib/mod
  </code></pre>
  
  <p>My POC C++ code, calling pes_init():</p>
  
  <pre><code>extern "C"{
  void pes_init_();
  }
  
  int main(){
      pes_init_();
      return 0;
  }
  </code></pre>
  
  <p>This can also be compiled to an object file, with icpc:</p>
  
  <pre><code>icpc -c PEStest.cpp
  </code></pre>
  
  <p>However I cannot figure out how to link the two object files, plus the truckload of fortran modules, into a final executable.
  I have tried just simply using icpc, but it cannot seem to be able to find the Fortran functions, even if I give it the location of the module files:</p>
  
  <pre><code>    icpc -I/home/debianuser/PES/PES_library/lib/mod -o test.x pes_shell.o PEStest.o
      pes_shell.o: In function `pes_shell_mp_f_':
      pes_shell.f90:(.text+0x595): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
      pes_shell.o: In function `pes_shell_mp_pes_init_':
      pes_shell.f90:(.text+0x5f0): undefined reference to `pes0_mp_pes0_init_'
      pes_shell.f90:(.text+0x603): undefined reference to `pes1c_mp_pes1_init_'
      PEStest.o: In function `main':
      PEStest.cpp:(.text+0x2b): undefined reference to `pes_init_'
  </code></pre>
  
  <p>EDIT:
  Pointing the linker to the directory where libpes.a can be found eliminates the problem of locating the function that was referenced in the c++ code, but icpc still cannot find the fortran functions that are being called from fortran codes:</p>
  
  <pre><code>  icpc -I/home/debianuser/PES/PES_library/lib/mod -L/home/debianuser/PES/PES_library/lib/pes-xyz -lpes -o test.x PEStest.o pes_shell_new.o
      pes_shell_new.o: In function `f_':
      pes_shell_new.f90:(.text+0x585): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
      pes_shell_new.o: In function `pes_init_':
      pes_shell_new.f90:(.text+0x5e0): undefined reference to `pes0_mp_pes0_init_'
      pes_shell_new.f90:(.text+0x5f3): undefined reference to `pes1c_mp_pes1_init_'
  </code></pre>