Module 如何编译具有接口、模块和子程序的多文件夹Fortran项目

Module 如何编译具有接口、模块和子程序的多文件夹Fortran项目,module,fortran,gfortran,subroutine,multifile,Module,Fortran,Gfortran,Subroutine,Multifile,我不熟悉Fortran。我正在做一个研究项目,我正在使用一个开源项目,其中有多个文件分布在多个文件夹中。我找到了每个程序的依赖关系,但不知道如何编译它们 我在三个文件夹中分发了源代码。 a) 模块 b) 接口 c) 子程序 我想在subroutines文件夹中运行一个名为“Main.f90”的程序,该程序依赖于模块和接口文件夹中的源代码 我使用eclipse进行文件夹结构和makefile编译 在此方面的任何帮助都将不胜感激 更新: 我遵循@MBR和@Stefan发布的答案,由于某些原因,VPA

我不熟悉Fortran。我正在做一个研究项目,我正在使用一个开源项目,其中有多个文件分布在多个文件夹中。我找到了每个程序的依赖关系,但不知道如何编译它们

我在三个文件夹中分发了源代码。 a) 模块 b) 接口 c) 子程序

我想在subroutines文件夹中运行一个名为“Main.f90”的程序,该程序依赖于模块和接口文件夹中的源代码

我使用eclipse进行文件夹结构和makefile编译

在此方面的任何帮助都将不胜感激

更新: 我遵循@MBR和@Stefan发布的答案,由于某些原因,VPATH无法在源代码中找到程序,因此我在Makefile中明确给出了这些源文件夹的路径。下面是我的makefile脚本

    .PHONY: Mopac_exe clean

    # Change this line if you are using a different Fortran compiler
    FORTRAN_COMPILER = gfortran
    SRC = src

    #make main program 
    Mopac_exe: subroutines mopac.o
        $(FORTRAN_COMPILER) mopac.o *.o -O2 -g  -o bin/Mopac_exe  -I Modules/

    #compile all the subroutines
    subroutines: interfaces
        $(FORTRAN_COMPILER) -c $(SRC)/subroutines/*.F90 -J Modules/Subroutines/ -I Modules/

    #compiles all the interfaces
    interfaces: modules
        $(FORTRAN_COMPILER) -c $(SRC)/interfaces/*.f90 -J Modules/


     # build all the modules and generate .mod file in Modules directory
     modules: build_vast_kind
        $(FORTRAN_COMPILER) -c $(SRC)/modules/*.f90 -J Modules/
        $(FORTRAN_COMPILER) -c $(SRC)/modules/*.F90 -J Modules/

    # compile vastkind.f90 files and generates the .mod file in Modules directory.Every other Modules and interfaces are dependent on this. 
    build_vast_kind:clean
       $(FORTRAN_COMPILER) -c $(SRC)/modules/vastkind.f90 -J Modules/

    clean:
       rm -f bin/Mopac_exe *.mod
       rm -f Modules/*.mod
       rm -f *.o
我编译了所有模块,并将其放在根文件夹的modules目录中。 一切顺利。我在构建可执行文件时出错。我得到以下错误

    gfortran mopac.o *.o -O2 -g     -o bin/Mopac_exe  -I Modules/
    mopac.o: In function `main':
    mopac.F90:(.text+0x27c1): multiple definition of `main'
    mopac.o:mopac.F90:(.text+0x27c1): first defined here
    getdat.o: In function `getdat_':
    getdat.F90:(.text+0x22): undefined reference to `iargc_'
    getdat.F90:(.text+0xf2): undefined reference to `getarg_'
    symr.o: In function `symr_':
    symr.F90:(.text+0xd3f): undefined reference to `symp_'
    writmo.o: In function `writmo_':
    writmo.F90:(.text+0x20c2): undefined reference to `volume_'
    collect2: error: ld returned 1 exit status
    make: *** [Mopac_exe] Error 1

`iargc_正在getdat文件中使用,iargc已经编译。为什么在使可执行文件表示未定义引用时出错?我遗漏了什么?

您可以创建一个类似这样的Makefile

F90=gfortran
FFLAGS = -O0
VPATH = modules:interfaces:subroutines:
MODOBJ = module1.o module2.o ...

your_executable: $(MODOBJ) main.o
        $(F90) main.o -o your_executable
%.o:%.f90
        $(F90) $(FFLAGS) -c $^ -o $@
VPATH
是Makefile将在其中查找源文件的目录路径,因此,如果您在
modules/
interfaces/
subroutines/
的根目录中编译源代码,您只需像这样设置
VPATH

如果您有许多对象,并且不想手工编写所有内容,可以使用以下技巧检索它们

F90 = gfortran
FFLAGS = -O0
VPATH = modules:interfaces:subroutines
SRCOBJ = $(wildcard modules/*f90)
MODOBJ = $(SRCOBJ:.f90=.o)

your_executable: $(MODOBJ) main.o
        $(F90) main.o -o your_executable
%.o:%.f90
        $(F90) $(FFLAGS) -c $^ -o $@

Makefile中的
通配符
命令允许您使用小丑
*
;然后,您只需说,在将在
$(SRCOBJ)
中检索的字符串中,您希望用
.o
替换
.f90
,以获得模块的文件名。

您可以像往常一样创建makefile。最大的问题应该是
.mod
文件。解决此问题的最简单方法是创建一个单独的文件夹,在其中存储和搜索这些文件


这可以通过
-J
-module
分别为
gfortran
ifort
标记来实现。

谢谢您MBR您的make文件对我很有意义。我试着写,但无法通过运行程序。问题是我为几个子程序创建了所有接口,这些接口在Main.f90程序中使用“USE”关键字列出。同样,Main.f90中也使用“USE”关键字使用模块。由于存在大型文件,我如何动态地包含和链接它们,而不是像您在回答中提到的那样列出每个文件,例如MODOBJ=module1.o module2.o。。。