computanjohn
computanjohn

Reputation: 143

Correctly Building Fortran Libraries And Using Them To Build Applications

I found a few previous questions regarding this, but was unable to find something specific for advice on correctly associating libraries and module files *.mod in a Makefile. I have a project directory named project where all source files for a library are in project/src, all compiled *.mod files are placed in project/include, and static libraries are created into the directory project/lib using the following:

ar rc myLibrary.a module1.o module2.o module3.o

Following this, I create an application code (a Fortran program that uses these libraries) in the directory project/applications. I have now, at the root level (that is, inside project) created a simple shell script that can build the application. This part is where I cannot get the process to work.

Here is what I am doing:

INCLUDELIB='./include'
LINKLIB='./lib'
INCLUDEOTHER=<include directories for other math libraries>
LINKOTHER=<link directories and link flags for other math libraries>
COMPILER='ifort'
COMPOPTS=<compiler flags, currently I use none>
# building the application:
$COMPILER $COMPOPTS -c ./applications/application.f90 -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER
$COMPILER $COMPOPTS application.o -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER -o application.out

This procedure does not work, and it gives Error in opening the compiled module file. Check INCLUDE paths.

I tried a few variants of the above from my readings on the web about this, and I hope that it is not some minor/silly error that I am overlooking that is leading to this.

Any help or advise will be much appreciated.

Upvotes: 0

Views: 1250

Answers (1)

Anthony Scemama
Anthony Scemama

Reputation: 1593

This is the message you get when things were not done right with the library (it's not your fault!).

*.mod files are compiler-specific, but not *.o files : *.mod files of gfortran are not compatible with *.mod files of ifort. Therefore, when you build a library, you should put all your API functions and subroutines outside of the modules. For example:

don't do this:

module x
 ...
contains

 subroutine sub_x
  ...
 end subroutine sub_x

end module

but do this instead:

module x
 ...
end module

subroutine sub_x
  use x
  ...
end subroutine sub_x

In this way you don't require the users to use mod files, and you can distribute your library as a .a or a .so archive.

In your case, the library you use was almost surely compiled with gfortran, so you are stuck with gfortran. The solution is to write another library as a wrapper around the original library. For example, do this for each function/subroutine you need:

subroutine wrapped_sub_x(arguments)
  use x
  call sub_x(arguments)
end

Then, you compile your wrapper library with gfortran in a .a archive, and you link it to your project with ifort. In your project, don't forget to call your wrapper library instead of the original library.

Upvotes: 1

Related Questions