我之前发现了一些有关此问题的问题,但无法找到有关在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.
我从网上的阅读中尝试了上述的一些变体,我希望这不是一些轻微/愚蠢的错误,我忽略了导致这一点。
非常感谢任何帮助或建议。
答案 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将其链接到项目。在您的项目中,不要忘记调用您的包装库而不是原始库。