I am trying to understand how to dynamically create and link a shared library in Fortran under Linux.
I have two files: The first one, liblol.f90
, looks like this:
subroutine func()
print*, 'lol!'
end subroutine func
I compile it with gfortran -shared -fPIC -o liblol.so liblol.f90
The second file, main.f90
, looks like this:
program main
call func()
end program main
When I now try to compile that with the command gfortran -L. -llol main.f90 -o main
, I get the following error:
/tmp/ccIUIhcE.o: In function `MAIN__':
main.f90:(.text+0xa): undefined reference to `func_'
collect2: ld returned 1 exit status
I do not understand why it says "undefined reference", since the output of nm -D liblol.so
gives me this:
w _Jv_RegisterClasses
0000000000201028 A __bss_start
w __cxa_finalize
w __gmon_start__
0000000000201028 A _edata
0000000000201038 A _end
0000000000000778 T _fini
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character_write
0000000000000598 T _init
00000000000006cc T func_
Is there any other parameter needed?
The linker reads individual object files and libraries, resolves references to external symbols, and writes out a single executable file or dynamic link library. The linker can also create a map file containing information about the segments and public symbols in the program.
Shared libraries are compiled code which is intended to be shared among several different programs. They are distributed as . so files in /usr/lib/. A library exports symbols which are the compiled versions of functions, classes and variables.
The only thing that has to be changed is the order of the arguments, as in
gfortran -L. main.f90 -llol -o main
Yes, only main.f90 and -llol are reversed. I hope this saves someone the year of his life I just lost on this. On a related note, if you are trying to compile a program which uses LAPACK or BLAS (which did not work for me and is why in the first place I tried to create a shared library myself), the same also applies. Write the name of the source file first:
gfortran mylapack.f90 -llapack -lblas -o mylapack
The reason for this can be found in the manual pages, see the top of http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html for the option -l:
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus,
foo.o -lz bar.o
searches libraryz
after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With