LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-22-2009, 10:38 AM   #1
Gamma_User
LQ Newbie
 
Registered: Jan 2009
Location: Brazil, Curitiba
Distribution: Debian
Posts: 18

Rep: Reputation: 0
Question Fortran 90 AND shared libraries.


I created a shared library with my most used mathematical functions using fortran 90. I intended to make my life easier, since I thought I could call the shared functions as simple as I call an intrinsic function like sin(x) or cos(x). However, I noted the functions in the shared library are treated as EXTERNAL functions. At this point my life became hard, because I have to interface my shared functions all the time. Is there a way to overcome this problem using fortran 90? Does this problem appear when using fortran 95?
 
Old 01-23-2009, 03:54 AM   #2
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,498

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
Using Fortran 90/95 you can either write a library using module interfaces or just simple functions. I think it all depends on how did you wrote the function library and how did you compile/link it. Consider the following (very simplified) example. I am using the Intel fortran compiler on this machine:
Code:
$ ls
my_sum.f90  test.f90
$ cat my_sum.f90
      FUNCTION my_sum(x,y)
      REAL:: my_sum
      REAL:: x, y
      WRITE(*,*) 'x = ', x
      WRITE(*,*) 'y = ', y
      my_sum = x + y
      END
$ ifort -c my_sum.f90
$ ls
my_sum.f90  my_sum.o  test.f90
$ ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
$ ls
libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ ln -s libtest.so.1 libtest.so
$ ls
libtest.so  libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ cat test.f90
      PROGRAM test
      REAL:: a, b, my_sum
      READ(*,*) a
      READ(*,*) b
      R = my_sum(a,b)
      WRITE(*,*) 'my_sum = ',R
      END PROGRAM test
$ ifort -L. test.f90 -ltest
$ ls
a.out  libtest.so  libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
$ echo $LD_LIBRARY_PATH
/home/colucix/test:/opt/intel/fc/10.1.015/lib:/opt/intel/cc/10.1.015/lib
$ ldd a.out
        linux-gate.so.1 =>  (0x0041e000)
        libtest.so.1 => /home/colucix/test/libtest.so.1 (0x00475000)
        libm.so.6 => /lib/libm.so.6 (0x004e3000)
        libc.so.6 => /lib/libc.so.6 (0x00111000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x002da000)
        libdl.so.2 => /lib/libdl.so.2 (0x0050c000)
        /lib/ld-linux.so.2 (0x00380000)
$ ./a.out
6
9
 x =    6.000000    
 y =    9.000000    
 my_sum =    15.00000
$
 
Old 01-23-2009, 02:15 PM   #3
Gamma_User
LQ Newbie
 
Registered: Jan 2009
Location: Brazil, Curitiba
Distribution: Debian
Posts: 18

Original Poster
Rep: Reputation: 0
Ok, I realized. But, suppose instead of my_sum.f90 I have a function
getsize(X) in a separated file:
Code:
function getsize(X)
  implicit none
  integer :: getsize
  real, dimension (:) :: X
  getsize=size(X)
end function getsize
In this case I need to interface the function getsize(X) in the main code:
Code:
program main
  implicit none
  real, dimension (10) :: A
! Interfacing the function getsize
  interface
     function getsize(X)
       implicit none
       integer :: getsize
       real, dimension (:) :: X
     end function getsize
  end interface

  write(*,*) getsize(A)
end program main
otherwise I'll get an error. That is the problem, I think it is not so practical to interface a shared function all the time.

You said it is possible write a library using module interfaces. I tried to do that, but it did not work. Suppose instead of the code above I have (in a separated file)
Code:
module mysize
contains
  function getsize(X)
    implicit none
    integer :: getsize
    real, dimension (:) :: X
    getsize=size(X)
  end function getsize
end module mysize
and as a main program
Code:
program main
  use mysize
  implicit none
  real, dimension (10) :: A

  write(*,*) getsize(A)
end program main
How can I proceed?

Thanks a lot!





Quote:
Originally Posted by colucix View Post
Using Fortran 90/95 you can either write a library using module interfaces or just simple functions. I think it all depends on how did you wrote the function library and how did you compile/link it. Consider the following (very simplified) example. I am using the Intel fortran compiler on this machine:
Code:
$ ls
my_sum.f90  test.f90
$ cat my_sum.f90
      FUNCTION my_sum(x,y)
      REAL:: my_sum
      REAL:: x, y
      WRITE(*,*) 'x = ', x
      WRITE(*,*) 'y = ', y
      my_sum = x + y
      END
$ ifort -c my_sum.f90
$ ls
my_sum.f90  my_sum.o  test.f90
$ ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
$ ls
libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ ln -s libtest.so.1 libtest.so
$ ls
libtest.so  libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ cat test.f90
      PROGRAM test
      REAL:: a, b, my_sum
      READ(*,*) a
      READ(*,*) b
      R = my_sum(a,b)
      WRITE(*,*) 'my_sum = ',R
      END PROGRAM test
$ ifort -L. test.f90 -ltest
$ ls
a.out  libtest.so  libtest.so.1  my_sum.f90  my_sum.o  test.f90
$ export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
$ echo $LD_LIBRARY_PATH
/home/colucix/test:/opt/intel/fc/10.1.015/lib:/opt/intel/cc/10.1.015/lib
$ ldd a.out
        linux-gate.so.1 =>  (0x0041e000)
        libtest.so.1 => /home/colucix/test/libtest.so.1 (0x00475000)
        libm.so.6 => /lib/libm.so.6 (0x004e3000)
        libc.so.6 => /lib/libc.so.6 (0x00111000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x002da000)
        libdl.so.2 => /lib/libdl.so.2 (0x0050c000)
        /lib/ld-linux.so.2 (0x00380000)
$ ./a.out
6
9
 x =    6.000000    
 y =    9.000000    
 my_sum =    15.00000
$

Last edited by Gamma_User; 01-23-2009 at 02:18 PM. Reason: TYPING ERROR
 
Old 01-26-2009, 02:29 AM   #4
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,498

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
Your last example works for me. Here is an excerpt from Stephen Chapman's "FORTRAN 95/2003 for scientist and engineers" (don't waste time to look for it in the web... I have the book)
Quote:
The easiest way to create an explicit interface is to place procedures in a module, and then use that module in the calling program unit. Any procedures placed in a module will always have an explicit interface.
So I just tried the code you provided and it works in the following way:
Code:
$ cat mysize.f90
module mysize
contains
  function getsize(X)
    implicit none
    integer :: getsize
    real, dimension (:) :: X
    getsize=size(X)
  end function getsize
end module mysize
$ ifort -c mysize.f90
$ ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
$ ln -s libtest.so.1 libtest.so
$ cat main.f90
program main
  use mysize
  implicit none
  real, dimension (10) :: A
  write(*,*) getsize(A)
end program main
$ ifort -L. main.f90 -ltest
$ ls
a.out  libtest.so  libtest.so.1  main.f90 mysize.f90  mysize.mod  mysize.o
$ export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
$ ./a.out
          10
 
Old 01-26-2009, 07:39 AM   #5
Gamma_User
LQ Newbie
 
Registered: Jan 2009
Location: Brazil, Curitiba
Distribution: Debian
Posts: 18

Original Poster
Rep: Reputation: 0
Hi colucix!

Perhaps the program worked because the mysize.mod and mysize.o files were in the directory. Try to remove them before using the command
Code:
ifort -L. main.f90 -ltest
Look at what happened in my computer:
Code:
hoggar%~/fortran/code ls
mysize.f90  uselib.f90
hoggar%~/fortran/code cat mysize.f90 
module mysize
contains
  function getsize(X)
    implicit none
    integer :: getsize
    real, dimension (:) :: X
    getsize=size(X)
  end function getsize
end module mysize
hoggar%~/fortran/code cat uselib.f90 
program main
  use mysize
  implicit none
  real, dimension (10) :: A

  write(*,*) getsize(A)
end program main
hoggar%~/fortran/code gfortran -c mysize.f90 
hoggar%~/fortran/code ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
hoggar%~/fortran/code ln -s libtest.so.1 libtest.so
hoggar%~/fortran/code rm *.mod *.o
hoggar%~/fortran/code ls
libtest.so  libtest.so.1  mysize.f90  uselib.f90
hoggar%~/fortran/code gfortran -L. uselib.f90 -ltest               
uselib.f90:2.12:

  use mysize
            1
Fatal Error: Can't open module file 'mysize.mod' for reading at (1)

Thank you!

Quote:
Originally Posted by colucix View Post
Your last example works for me. Here is an excerpt from Stephen Chapman's "FORTRAN 95/2003 for scientist and engineers" (don't waste time to look for it in the web... I have the book)

So I just tried the code you provided and it works in the following way:
Code:
$ cat mysize.f90
module mysize
contains
  function getsize(X)
    implicit none
    integer :: getsize
    real, dimension (:) :: X
    getsize=size(X)
  end function getsize
end module mysize
$ ifort -c mysize.f90
$ ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
$ ln -s libtest.so.1 libtest.so
$ cat main.f90
program main
  use mysize
  implicit none
  real, dimension (10) :: A
  write(*,*) getsize(A)
end program main
$ ifort -L. main.f90 -ltest
$ ls
a.out  libtest.so  libtest.so.1  main.f90 mysize.f90  mysize.mod  mysize.o
$ export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
$ ./a.out
          10

Last edited by Gamma_User; 01-26-2009 at 07:41 AM. Reason: grammatical error
 
Old 01-26-2009, 08:03 AM   #6
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,498

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
It works for me. But...
1) you have to preserve the mysize.mod and put it in some Include path, since it is used during the compilation of the main program
2) you have to tell to the system where to find the shared library, that is change the LD_LIBRARY_PATH environment variable accordingly OR use ldconfig to add the directory containing the libraries to the cache of the shared objects.
This equals to provide a devel package, that is: if you want to share with others the newly created libraries you have to provide both the libs and the includes. The library will be enough for already compiled executables linking against it. In addition the .mod will be necessary to develop and compile new applications!

I try again, just to be sure:
Code:
$ pwd
/home/colucix/test_lib
$ ls
include  lib  main.f90  mysize.f90
$ ifort -c mysize.f90
$ ld -o libtest.so.1 -dy -G -h libtest.so.1 *.o
$ ls
include  lib  libtest.so.1  main.f90  mysize.f90  mysize.mod  mysize.o
$ rm mysize.o
$ mv libtest.so.1 lib/
$ mv mysize.mod include/
$ ln -s libtest.so.1 lib/libtest.so
$ ls -l lib/
total 12
lrwxrwxrwx 1 colucix users   12 Jan 26 14:57 libtest.so -> libtest.so.1
-rwxr-xr-x 1 colucix users 1327 Jan 26 14:54 libtest.so.1
$ ifort -I./include -L./lib main.f90 -ltest
$ export LD_LIBRARY_PATH=$(pwd)/lib:${LD_LIBRARY_PATH}
$ echo $LD_LIBRARY_PATH
/home/colucix/test_lib/lib:/opt/intel/fc/10.1.015/lib:/opt/intel/cc/10.1.015/lib
$ ./a.out
          10

Last edited by colucix; 01-26-2009 at 08:18 AM. Reason: corrected a typo
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
gxine: error while loading shared libraries: libmozjs.so: cannot open shared object.. empcrono Slackware 10 11-10-2008 07:33 PM
error while loading shared libraries: libstdc++.so.5: cannot open shared object file PaulyWally Debian 2 10-18-2008 05:59 PM
error while loading shared libraries: libgvc.so.3: cannot open shared object file coolrock Slackware 6 01-17-2007 05:10 PM
fortran libraries rbrown04 Programming 1 06-07-2005 10:52 PM
error while loading shared libraries: libdb-4.1.so: cannot open shared object file putquery8581 Linux - Software 1 10-01-2004 07:03 AM


All times are GMT -5. The time now is 09:21 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration