Cross-Language Linking in Meson: FORTRAN & C++

Hi everyone,

I am currently working on linking a FORTRAN simulation with a dependency on a C++ library after compiling it. I successfully managed to compile the two static libraries the code depends upon, and also compile the main simulation code. It is at this stage that I seem to have misconfigured Meson as the linker is unable to find the library as evidenced by error messages such as

/usr/bin/ld: blub_file_bin.F:(.text+0x279eb): undefined reference to `tecini112_'

When I check the library file with nm libdummy.a | grep tecini112, I find the respective routine:

0000000000004050 T tecini112

Within the source code references to the library are mostly made through the use of a .for file , i.e. for, i.e. within 3 files of the simulation source it is imported through

include "dummy/dummy.for"

Which defines the interface, i.e. for tecini112:

      INTERFACE

      INTEGER(4) FUNCTION tecini112
      & (Title,
      &  Variables,
      &  FName,
      &  ScratchDir,
      &  FileType,
      &  Debug,
      &  VIsDouble)
          CHARACTER(LEN=*) Title
          CHARACTER(LEN=*) Variables
          CHARACTER(LEN=*) FName
          CHARACTER(LEN=*) ScratchDir
          INTEGER(4)       FileType
          INTEGER(4)       Debug
          INTEGER(4)       VIsDouble
      END FUNCTION tecini112

      END INTERFACE

There also exist accompanying .f90, and .inc files to the .for file, all of which are not included in meson right now. Which is also where the error might originate from. dummy/include is the incdir, and lib_one is built from dummy/src, i.e. the library is then built by

lib_one = static_library(
    'dummy',
    sources: dummy_src,
    include_directories: incdir,
    dependencies: mpicpp,
    install: false,
)

and the executable is built as

executable(
    'Simulator',
    sources: srcs,
    link_with: [lib_one, lib_two],
    link_args: ['-g', '-lquadmath', '-fbacktrace'],
    fortran_args: [<bunch of flags>],
    dependencies: mpif,
)

Here is furthermore the link command of meson:

gcc  -o SIMULATOR <a bunch of object files> -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -Wl,--start-group libdummy.a lib2t.a -g -lquadmath -fbacktrace -pthread -Wl,-rpath -Wl,/usr/local/lib -Wl,--enable-new-dtags -L/usr/local/lib -lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lmpi -Wl,-rpath -Wl,/usr/local/lib -Wl,--enable-new-dtags -L/usr/local/lib -lmpi -Wl,-rpath -Wl,/usr/local/lib -Wl,--enable-new-dtags -L/usr/local/lib -lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lmpi -lgfortran -lm -Wl,--end-group

Would be really thankful for any pointers.

Thank you for reading this far,
Ludger

Check whether your Fortran compiler adds an underscore to external routine names, and consider providing a BIND(C) interface that matches the routine name in the C library.

Alternatively, consider changing the name of the routine in the C library to match what the Fortran routine expects.

Matching decorated names is one aspect; the calling sequences must also match.

You indicated this is a C++ library. I’m not positive about this (perhaps someone else can confirm or refute) but the source for the library function you want to call needs to have been wrapped in extern "C" { ... } so that it presents a C interface that Fortran can call (using its iso_c_bindings and bind(C) facilities). This may require you to write your own bit of C++ wrapper code if the library doesn’t provide a C interface.