Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared library in Fortran, minimal example does not work

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?

like image 659
Markus Avatar asked Apr 11 '12 18:04

Markus


People also ask

What is a linker Fortran?

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.

What is shared library in Ubuntu?

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.


1 Answers

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 library z after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.

like image 126
Markus Avatar answered Nov 15 '22 21:11

Markus