正确构建Fortran库并使用它们构建应用程序

时间:2015-02-09 16:42:02

标签: module fortran static-libraries include-path

我之前发现了一些有关此问题的问题,但无法找到有关在Makefile中正确关联库和模块文件*.mod的建议的具体内容。 我有一个名为project的项目目录,其中库的所有源文件都在project/src中,所有已编译的*.mod文件都放在project/include中,并且静态库被创建到目录project/lib使用以下内容:

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

在此之后,我在目录project/applications中创建了一个应用程序代码(使用这些库的Fortran程序)。我现在在根级(即project内)创建了一个可以构建应用程序的简单shell脚本。这部分是我无法让这个过程发挥作用的地方。

这是我正在做的事情:

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

此过程不起作用,它提供Error in opening the compiled module file. Check INCLUDE paths.

我从网上的阅读中尝试了上述的一些变体,我希望这不是一些轻微/愚蠢的错误,我忽略了导致这一点。

非常感谢任何帮助或建议。

1 个答案:

答案 0 :(得分:1)

这是你在图书馆没有完成任务时得到的信息(这不是你的错!)。

*.mod个文件是编译器特定的,但不是*.o个文件:gfortran的*.mod个文件与ifort的*.mod个文件不兼容。因此,在构建库时,应该将所有API函数和子例程放在模块之外。例如:

不要这样做:

module x
 ...
contains

 subroutine sub_x
  ...
 end subroutine sub_x

end module

但请改为:

module x
 ...
end module

subroutine sub_x
  use x
  ...
end subroutine sub_x

通过这种方式,您不需要用户使用mod文件,您可以将您的库分发为.a.so存档。

在你的情况下,你使用的库几乎肯定是用gfortran编译的,所以你被gfortran困住了。解决方案是将另一个库写为原始库的包装器。例如,这样做 对于您需要的每个函数/子例程:

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

然后,在.a存档中使用gfortran编译包装器库,然后使用ifort将其链接到项目。在您的项目中,不要忘记调用您的包装库而不是原始库。