CMake undefined and duplicate symbols when building executable. Fortran77 C mix

138 Views Asked by At

I have a fortran 90 program which calls Sundials CVODE via the FCVODE inteface. Sundials is written in C, but they provide two interfaces to fortran. One interface is for fortran 77 applications, and one uses modern fortran methods (iso_c_binding).

My code uses the fortran 77 interface (just the way it ended up, I know iso_c_binding would be better)

Here is my project (dev branch): https://github.com/Nicholaswogan/PhotochemPy/tree/dev

My goal is to write a CMakesLists.txt which compiles all the fortran and C in one swoop. I have done this, but it only works with some compiler combinations and opperating systems. For example, on MacOS with clang 12.0.5 and gfortran 11.1.0, everything works great. But, on MacOS, when I switch to gcc 11.1.0 (instead of clang), I get an error when linking my executable:

[ 98%] Building Fortran object CMakeFiles/photo.run.dir/src/main.f90.o
[100%] Linking Fortran executable photo.run
duplicate symbol '_F2C_CVODE_linsol' in:
    lib/libsundials_fcvode.a(fsunlinsol_band.c.o)
    lib/libsundials_fcvode.a(fcvnulllinsol.c.o)
duplicate symbol '_F2C_CVODE_matrix' in:
    lib/libsundials_fcvode.a(fsunmatrix_band.c.o)
    lib/libsundials_fcvode.a(fcvnullmatrix.c.o)
ld: 2 duplicate symbols for architecture x86_64
collect2: error: ld returned 1 exit status
make[2]: *** [photo.run] Error 1
make[1]: *** [CMakeFiles/photo.run.dir/all] Error 2
make: *** [all] Error 2

I have looked at libsundials_fcvode.a and libsundials_fcvode.a, and they do contain these duplicate symbols. However, when I compile with clang + gfortran, these libraries also have these duplicate symbols, but, these compilers don't seem bothered by it in this case.

Also, on Ubuntu 20.04 with gcc 9 and gfortran 9, I get an undefined symbol:

[ 98%] Building Fortran object CMakeFiles/photo.run.dir/src/main.f90.o
[100%] Linking Fortran executable photo.run
/usr/bin/ld: lib/libsundials_fcvode.a(fcvband.c.o): in function `FCVBandJac':
fcvband.c:(.text+0x141): undefined reference to `fcvbjac_'
/usr/bin/ld: lib/libsundials_fcvode.a(fcvode.c.o): in function `FCVf':
fcvode.c:(.text+0x50): undefined reference to `fcvfun_'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/photo.run.dir/build.make:91: photo.run] Error 1
make[1]: *** [CMakeFiles/Makefile2:711: CMakeFiles/photo.run.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

This missing symbol is very puzzling because It is not missing! I've used nm to to interogate the library I'm linking to, and the symbols are there:

...
 cvode_funcs.f90.o:
0000000000000250 T fcvbjac_
0000000000000000 T fcvfun_
...

My question: What common items are missing from a CMakesList.txt, that cause these sorts of problems? Or is this sort of problem bound to happen when mixing fortran and C without iso_c_binding?

EDIT:

I ended up spending the time switching from the fortran 77 interface to the modern fortran C interface, which uses iso_c_binding. Every compiler I have tried works.

0

There are 0 best solutions below