使模块像内部 Fortran 模块一样工作
Making a module work like an intrinsic Fortran module
我在名为 mymodule.f90
的文件中有一个模块 module1
。我应该怎么做才能使 module1
像 fortran 内部模块一样可用?即它只需要在使用它的任何程序、子例程或函数的 use 语句 (use module1
) 中调用,但我编译这些程序时不需要 link /path/to/mymodule/
。
我使用 gfortran,但将来可能还必须使用 Intel fortran 编译器。
所以也许我误会了你,但你想使用 module 而不必告诉编译器在哪里可以找到 .mod 文件(包含任何接口定义module1
exports), 或者可以找到目标代码的链接器?
如果是这样,对于 GFortran,解决方案是下载 GCC 源代码,添加您自己的 module 作为内部 module,然后构建您自己的 GFortran 自定义版本。提醒一句,除非您熟悉 GFortran/GCC 内部结构,否则虽然这不是火箭科学,但也不是微不足道的。
对于 Intel Fortran,您可能无法访问编译器的源代码,我想您运气不好。
我的建议是忘记这一点,而是告诉 compiler/linker 在哪里可以找到您的 .mod 文件和目标文件。有 make、cmake 等工具可以帮助您自动执行此操作。
编译mymodule.f90
时,您将获得一个目标文件(mymodule.o
)和一个模块文件(mymodule1.mod
)。编译器在编译 use mymodule1
的其他文件时需要访问模块文件,而链接器在生成二进制文件时需要访问目标文件。
您不需要指定内部模块的位置,因为它们内置于编译器中。对于您的模块,情况并非如此:您可以通过文件位置允许编译器找到文件的方式来设置您的环境,而无需在编译或链接命令中明确指定它们的路径,但事实是你没看到不代表没有发生。
对于Intel编译器,答案是https://software.intel.com/en-us/node/694273 :
Directories are searched for .mod files in this order:
1 Directory of the source file that contains the USE statement.
2 Directories specified by the module path compiler option.
3 Current working directory.
4 Directories specified by the -Idir (Linux* and OS X*) or /include (Windows*) option.
5 Directories specified with the CPATH or INCLUDE environment variable.
6 Standard system directories.
对于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
您应该很清楚,编译器将无法理解其他编译器创建的模块文件,甚至无法理解同一编译器的足够多的不同版本。因此,您需要为您使用的每个编译器复制一份 "always available" 模块,如果您使用多个版本的编译器,您可能每个版本最多需要一个 - 每个版本都在不同的目录中以避免错误.
如你所见,这并不是特别实用,确实离普遍做法还差得很远。在编译命令中指定相关模块文件的路径通常对用户来说更容易、更清晰。如果您使用诸如 make 之类的工具编译代码,这将非常容易设置。
最后,请记住,如果您对模块文件进行了这样的安排,您还需要在链接阶段对相应的目标文件进行安排。
我在名为 mymodule.f90
的文件中有一个模块 module1
。我应该怎么做才能使 module1
像 fortran 内部模块一样可用?即它只需要在使用它的任何程序、子例程或函数的 use 语句 (use module1
) 中调用,但我编译这些程序时不需要 link /path/to/mymodule/
。
我使用 gfortran,但将来可能还必须使用 Intel fortran 编译器。
所以也许我误会了你,但你想使用 module 而不必告诉编译器在哪里可以找到 .mod 文件(包含任何接口定义module1
exports), 或者可以找到目标代码的链接器?
如果是这样,对于 GFortran,解决方案是下载 GCC 源代码,添加您自己的 module 作为内部 module,然后构建您自己的 GFortran 自定义版本。提醒一句,除非您熟悉 GFortran/GCC 内部结构,否则虽然这不是火箭科学,但也不是微不足道的。
对于 Intel Fortran,您可能无法访问编译器的源代码,我想您运气不好。
我的建议是忘记这一点,而是告诉 compiler/linker 在哪里可以找到您的 .mod 文件和目标文件。有 make、cmake 等工具可以帮助您自动执行此操作。
编译mymodule.f90
时,您将获得一个目标文件(mymodule.o
)和一个模块文件(mymodule1.mod
)。编译器在编译 use mymodule1
的其他文件时需要访问模块文件,而链接器在生成二进制文件时需要访问目标文件。
您不需要指定内部模块的位置,因为它们内置于编译器中。对于您的模块,情况并非如此:您可以通过文件位置允许编译器找到文件的方式来设置您的环境,而无需在编译或链接命令中明确指定它们的路径,但事实是你没看到不代表没有发生。
对于Intel编译器,答案是https://software.intel.com/en-us/node/694273 :
Directories are searched for .mod files in this order:
1 Directory of the source file that contains the USE statement.
2 Directories specified by the module path compiler option.
3 Current working directory.
4 Directories specified by the -Idir (Linux* and OS X*) or /include (Windows*) option.
5 Directories specified with the CPATH or INCLUDE environment variable.
6 Standard system directories.
对于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
您应该很清楚,编译器将无法理解其他编译器创建的模块文件,甚至无法理解同一编译器的足够多的不同版本。因此,您需要为您使用的每个编译器复制一份 "always available" 模块,如果您使用多个版本的编译器,您可能每个版本最多需要一个 - 每个版本都在不同的目录中以避免错误.
如你所见,这并不是特别实用,确实离普遍做法还差得很远。在编译命令中指定相关模块文件的路径通常对用户来说更容易、更清晰。如果您使用诸如 make 之类的工具编译代码,这将非常容易设置。
最后,请记住,如果您对模块文件进行了这样的安排,您还需要在链接阶段对相应的目标文件进行安排。