【问题标题】:Are fortran library required if using only modules?如果仅使用模块,是否需要 fortran 库?
【发布时间】:2014-07-31 21:52:43
【问题描述】:

我正在尝试清理 fortran make 进程以进行分发。目前,制作了两个库,然后编译链接到库并包含模块文件的可执行文件。我从以前的答案 (Distribute compiled fortran library with module files) 中看到,您无法摆脱模块文件,并且它们对于每台机器和编译器都可能不同。这很烦人。

但是,我的库中的代码完全由模块组成。似乎我根本不需要库部分;我可以只包含模块。我已经尝试过了,它确实可以在小示例上编译和运行。

这是否总是有效(当我只有库中的模块时)?这是最佳实践吗?我是否应该考虑重写我的库而不是使用模块,这样我就可以避免所有这些编译器依赖项并只分发 lib*.a 文件?这就是this document 所指的使用子模块(没有人支持static lib with many modules

【问题讨论】:

    标签: module fortran shared-libraries


    【解决方案1】:

    这实际上取决于您的库中的功能。它只有几个声明吗?那么.mod 文件就足够了,但是为什么不在这种简单的情况下分发源呢?

    您的所有公共程序是否都足够简单,以至于它们不需要显式接口并且位于模块之外?那么你就不需要任何.mod 文件了。

    您是否有一个简单的公共模块或包含公共 API 的包含文件,其余部分是私有的?然后,您可以分发 API 模块的源代码或包含文件。我建议在这个模块中只放置接口块和其他声明。

    注意一个重要问题。您可以避免使用不可移植的.mod 文件(使用接口锁或类似方法),但如果程序使用一些更高级的参数传递,它们的 ABI 通常不能在不同编译器甚至某些编译器版本之间移植。您将能够编译它并在调用您的库时出现神秘的崩溃。

    子模块可以改变这一切,但实际上我并不期望它们会解决编译器之间的可移植性。您的库的用户仍然需要您拥有的相同编译器。确实,封闭源代码软件的接口会更容易,但编译器之间的可移植性并不高。

    【讨论】:

    • 这段代码都在模块中——没有外部声明。可能有 20 个文件,其中包含 30 个或更多模块,至少定义了许多派生类型和更多过程。用户的PROGRAM 最终几乎成为一个脚本文件USEing 并调用这些模块。
    • 还是有一些误会。如果你写“但是,我的库中的代码完全由模块组成。看起来我根本不需要库部分;我可以只包含模块。”什么是“包含模块”?什么是“库部分”?您需要一些包含已编译代码的文件、一个目标文件 (.o .obj) 或一个库 (.so .a .dll)。只有在模块中只有声明且没有可执行代码时,您才能摆脱 .mod。
    • 如果您的意思是“仅模块”,仅.f90 源文件就足够了,那么是的,当然,您不必构建单独的库,您可以调用 f90 library.f90 main.f90并有结果,但我相信这是很明显的。
    • 我很抱歉糟糕的 CS 词汇令人困惑。所以库存档替换了目标文件,而不是“.mod”编译的模块文件。现在很清楚了。在您的原始帖子中,您是否建议在我定义所有接口的地方分发一个库存档和一个模块源文件?有没有这样的例子?
    • 库是闭源的还是开源的?
    【解决方案2】:

    您可以从库 lib*.a 或从目标文件进行链接。两者都至少依赖于平台,因此比源代码更难分发。库文件可能具有文件较少的优点。无论哪种情况,从 lib*a 或目标文件链接,您都可以将代码作为要调用的过程库呈现给用户。如果您不想分发源代码,那么无论您支持多少平台,您都必须进行编译。模块是现代 Fortran 的一个主要优势,它可以自动检查过程的实际参数和虚拟参数。例如,与 C 头文件相比,它们具有自动生成的优点,但缺点是生成依赖于编译器的中间文件。如果您正在向其他程序员提供程序,那么不向他们提供此接口检查似乎是个坏主意。如果你想隐藏你的源代码,那么你可以编写描述过程的接口块,并只分发这个源代码供它们编译。

    【讨论】:

      猜你喜欢
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多