在不构建库或复制源代码的情况下,我无法理解是否/如何在多个 Fortran 项目之间共享代码。
我在 Linux 系统上将 Eclipse/Photran 与英特尔编译器 (ifort) 一起使用,但我相信与特定工具相比,模块的概念问题更大。
这是一个简单的示例:在 ~/workspace/cow 我有一个源目录 (src),其中包含 cow.f90(程序)和两个模块 m_graze 和 m_moo,分别位于 m_graze.f90 和 m_moo.f90 中。该项目正确构建和链接以创建可执行的“cow”。可执行文件和模块(m_graze.mod 和 m_moo.mod)存储在 ~/workspace/cow/Debug 和目标文件存储在 ~/workspace/cow/Debug/src
之后,我创建了 ~/workplace/sheep,并将 src/sheep.f90 作为程序,将 src/m_baa.f90 作为模块 m_baa。我想在sheep.f90 中“仅使用m_graze:反刍”来访问rumate() 子例程。我可以只复制 m_graze.f90 但这可能导致代码不同步并且没有考虑 m_graze 可能具有的任何依赖项。由于这些原因,我宁愿将 m_graze 留在牛项目中,并针对它编译和链接sheep.f90。
如果我尝试编译绵羊项目,我会收到如下错误:
error #7002: Error in opening the compiled module file. Check INCLUDE paths. [M_GRAZE]
在属性:羊的项目参考下,我可以选择牛项目。在 Properties:Fortran Build:Settings:Intel Compiler:Preprocessor 下,我可以将 ~/workspace/cow/Debug(模块文件的位置)添加到包含目录列表中,因此编译器现在可以找到 cow 模块并编译sheep.f90。但是,链接器会因以下内容而死:
Building target: sheep
Invoking: Intel(R) Fortran Linker
ifort -L/home/me/workspace/cow/Debug -o "sheep" ./src/sheep.o
./src/sheep.o: In function `sheep':
/home/me/workspace/sheep/src/sheep.f90:11: undefined reference to `m_graze_mp_ruminate_'
这通常可以通过将库和库路径添加到链接器设置来解决,除非没有适当的库可以链接(这是 Fortran,而不是 C。)
cow 项目完全有能力将 cow.f90、m_graze.f90 和 m_moo.f90 编译并链接到一个可执行文件中。然而,虽然sheep 项目可以编译sheep.f90 和m_baa.f90 并且可以找到模块m_graze.mod,但它似乎无法找到m_graze 的符号,即使系统上存在所有必要的信息以便它这样做.
让 ifort 的链接器部分找到丢失的部分并将它们放在一起似乎是一个简单的配置问题,但我不知道需要在 Photran UI 的哪个位置输入什么魔法词才能实现这一点。
我承认对 C 和 C 构建过程完全缺乏兴趣和能力,我宁愿避免创建库(.a 或 .so)的转移,除非这是完成这项工作的唯一方法。
最终,我正在寻找一个纯 Fortran 解决方案来解决这个问题,这样我就可以保留一份源代码副本,而不必手动维护一堆自定义 Makefile。
那么这可以做到吗?
如果这已经记录在某处,我们深表歉意;Google 只向我展示了简单的构建示例、如何创建模块以及如何与现有库链接。似乎没有(m)任何不涉及复制源代码的模块的代码重用示例。
编辑
正如受访者指出的那样,.mod 文件是必要的,但还不够;必须在链接阶段指定目标代码(以 m_graze.o 的形式)或静态或共享库。.mod 文件描述了目标代码/库的接口,但两者都是构建最终可执行文件所必需的。
对于这样一个过于简单的玩具问题,这足以回答所提出的问题。
在具有更复杂依赖项的大型项目中(在我的例子中,F90 的 80+KLOC 链接到 LAPACK95 的 MKL 版本),IDE 或工具链可能缺乏足够的自动或用户界面设施来共享单个规范的源文件集一个可行的策略。选择似乎是在冒着重复源文件不同步的风险、放弃 IDE 的许多好处(即避免手动创建 make/CMake/SCons 文件)之间,或者很可能两者兼而有之。虽然修订控制系统和良好的代码组织可以提供帮助,但很明显,鉴于 Eclipse 的当前状态,在项目之间共享单个规范的源文件集绝非易事。