我在名为module1
的文件中有一个模块mymodule.f90
。为了使module1
像fortran内在模块一样可用,我该怎么做?即,仅需要在使用它的任何程序,子例程或函数中的use语句(use module1
)中调用它,但我编译这些过程时不需要链接/path/to/mymodule/
。
我使用gfortran,但将来可能还要使用Intel fortran编译器。
答案 0 :(得分:3)
所以也许我对您有误解,但是您想使用模块而不必告诉编译器在哪里可以找到.mod文件(其中包含任何module1
导出的接口定义)或链接程序在哪里可以找到目标代码?
如果是这样,对于GFortran,解决方案是下载GCC源代码,添加您自己的模块作为内部模块,然后构建自己的自定义版本的GFortran。提醒一下,除非您熟悉GFortran / GCC的内部原理,尽管这不是火箭科学,但这也不是小事。
对于Intel Fortran,您大概无法访问编译器的源代码,我想您很走运。
我的建议是忘记此事,而是告诉编译器/链接器可以在哪里找到.mod文件和目标文件。有诸如make,cmake等工具可以帮助您自动化。
答案 1 :(得分:2)
编译mymodule.f90
时,将获得一个目标文件(mymodule.o
)和一个模块文件(mymodule1.mod
)。编译器在编译use mymodule1
的其他文件时需要访问模块文件,而链接器在生成二进制文件时需要访问目标文件。
您不需要指定内部模块的位置,因为它们是内置在编译器中的。对于模块而言,情况并非如此:您可以通过以下方式设置环境:文件的位置允许编译器查找文件,而无需在编译或链接命令中明确指定其路径,但是事实是您看不到它并不意味着它没有发生。
对于Intel编译器,答案由https://software.intel.com/en-us/node/694273给出:
按以下顺序在目录中搜索.mod文件:
1包含USE语句的源文件目录。
2个由模块路径编译器选项指定的目录。
3当前工作目录。
-Idir(Linux *和OS X *)或/ include(Windows *)选项指定的4个目录。
使用CPATH或INCLUDE环境变量指定的5个目录。
6个标准系统目录。
对于gfortran,我没有找到如此明确的有序列表,但是相关信息可以在
中找到https://gcc.gnu.org/onlinedocs/gfortran/Directory-Options.html
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options
对您应该清楚的是,编译器将无法理解其他编译器甚至同一编译器的足够不同版本创建的模块文件。因此,对于使用的每个编译器,您都需要一个“始终可用”模块的副本;如果您使用的是多个版本的编译器,则每个版本最多需要一个版本-每个版本都位于不同的目录中,以避免出错。
正如您所看到的,这不是特别实用,并且确实与通常的实践相去甚远。对于用户来说,在编译命令中指定相关模块文件的路径通常更容易,更清晰。如果您使用诸如make之类的工具编译代码,则设置起来非常容易。
最后,请记住,如果对模块文件进行了这种安排,则还需要在链接阶段对相应的目标文件进行安排。