【问题标题】:How to compile Fortran FUNCTION/SUBROUTINE in separate files into a single MODULE如何将单独文件中的 Fortran FUNCTION/SUBROUTINE 编译成单个 MODULE
【发布时间】:2017-07-21 08:19:15
【问题描述】:

通常,当我编写 Fortran 函数的集合时,我会将它们放入 MODULE 中,如下所示:

!mystuff.f90
MODULE mymodule
IMPLICIT NONE

CONTAINS

  SUBROUTINE mysubroutine1(a,b)
  !code
  END SUBROUTINE

  SUBROUTINE mysubroutine2(a,b)
  !code
  END SUBROUTINE

  !lots more functions and subroutines

END MODULE

我成功地编译它像这样gfortran -c mystuff.f90。这会创建mystuff.o,我可以在我的主程序中使用它。

但是,我的MODULE 中的函数/子例程的数量和单个大小已经变得非常庞大,我真的需要将其拆分为不同的文件。

!mysubrtn1.f90
SUBROUTINE mysubroutine1(a,b)
!code
END SUBROUTINE

! mysubrtn2.f90
SUBROUTINE mysubroutine2(a,b)
!code
END SUBROUTINE

等等……

但我仍然希望将所有这些功能保留在一个单个 MODULE 中。如何告诉编译器编译 mysubrtn1.f90mysubrtn2.f90、... 中的函数,以便在 .o 文件中生成单个模块?

【问题讨论】:

  • 如果你有一个最近的编译器,你可能应该研究一下最近引入的 Fortran 的submodule 功能。仔细看,你会在这个话题上找到 Qs 和 As。 submodules 不仅允许您将大模块分解成更小的部分,它们还允许您分离接口和实现。这通常很有用。

标签: fortran include gfortran


【解决方案1】:

您可以简单地使用include 来包含另一个 Fortran 源代码文件:

!mystuff.f90
MODULE mymodule
IMPLICIT NONE

CONTAINS

  include 'mysubrtn1.f90'
  include 'mysubrtn2.f90'

  !lots more functions and subroutines

END MODULE

来自here

INCLUDE 语句指示编译器停止读取语句 从当前文件中读取包含的文件或文本中的语句

因此您可以看到生成的模块仍将包含两个子例程。


如果你的编译器支持的话,另一种实现相同目的的方法是使用预处理器指令:

#include "filename"

【讨论】:

  • 非常好!快速跟进问题:在我的每个函数中,我都有USE xyz。显然,我可以从每个文件中取出该行并将其放在mystuff.f90 的开头。但是将它留在每个文件中还有mystuff.f90的开头有什么害处吗?
  • 你的意思是模块的作用域和函数/子程序的作用域有什么区别?
  • 我想我理解这种差异。将USE xyz 放在mystuff.f90 的顶部将使xyz 可用于该模块中的所有函数/子例程。我只是习惯将它包含在每个这些函数/子例程中。 (我认为这没有区别);我只是想知道如果我在mystuff.f90 的开头有USE xyz 是否也在每个函数/子例程中,我是否会混淆编译器。如果我错了,请纠正我。
  • make 中使用这种技术是否存在问题,因为对included 文件的更改不会触发对父文件的重建? submodules 会帮助解决这个问题吗?
  • 这很好,@arclight。为了解决这个问题,我认为您只需将您的子例程文件包含为 mystuff.o 模块的依赖项。
【解决方案2】:

为了便于阅读,最好将大模块分成更易于管理的块。每个较小的模块可以单独编译,并在另一个“主”模块中使用,然后在主程序中使用。这种方法的主要好处是您可以拥有各种非常通用的模块,并且只选择目前有用的程序/数据。例如:

module mod_1
    implicit none
    subroutine proc_1
        ! ...
    end subroutine
    ! other procedures, etc.
end module mod_1

等等,对于每个单独的模块。然后将它们收集在一个模块中。

module collection
    use mod_1, only: proc_1  ! pick & choose what to use
    use mod_2
    use mod_3
    ! ...
end module collection

program main
    use collection
    implicit none
    ! ...
end program main

当您编译主程序时,您可以链接到每个必要的目标文件,甚至可以将它们组合到一个存档/库中并链接到该文件。

【讨论】:

  • 好的,所以另一种策略是为每个我的函数定义一个单独的模块,然后将这些模块放入一个更大的模块中。我没听错吗?
  • 没错。我只是对原始答案进行了一些扩展。虽然,我认为@Alexander Vogt 的回答用更少的编译步骤完成了同样的任务!
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
相关资源
最近更新 更多