The following scenario: I have a large function library, which is programmed in Fortran and is available as a shared library for different systems (*.dll / *.dylib / *.so). From this library, some functions are now to be called in another project. However, no matter how I do it, I have no success.
I have put together a minimal example to better understand the whole thing:
Library myLib.F90:
module mylibmod
implicit none
public :: sayHello
contains
subroutine sayHello()
!GCC$ ATTRIBUTES DLLEXPORT :: sayHello
print*, 'Hello Fortran!'
end subroutine sayHello
end module mylibmod
Call libCall.f90:
program libCall
call sayHello()
continue
end program libCall
The library is compiled using gfortran for all platforms. The calls used with Windows are:
gfortran -c -o myLib.o -fPIC .\src\mylib.F90
, gfortran -shared -fPIC -o mylib.dll myLib.o
and gfortran -o libCall.exe -fPIC .\src\libCall.f90 mylib.dll
At the last command the linker throws me an error, that the function name can't be found in the library. [..] undefined reference to "sayhello_"
. However, when I take a look at the exported functions in the DLL I can find the reference:
As a next step I tried to simplify the whole thing a bit so I removed the encapsulation in a module:
myLib.f90:
subroutine sayHello()
!GCC$ ATTRIBUTES DLLEXPORT :: sayHello
print*, 'Hallo Fortran!'
end subroutine sayHello
Now, using the same commands, the linker finds the reference and the executable gets linked without any problem. Accordingly, the problem seems to be the encapsulation of the subroutine in the module.
Finally to my actual question: what am I doing wrong or do I have to change so that the call also works for functions in modules? - The library I want to use is completely set up in modules.