如何编译具有接口,模块和子例程的多文件夹Fortran Project

时间:2013-08-27 11:18:54

标签: module fortran gfortran subroutine multifile

我是Fortran的新手。我正在研究一个研究项目,我正在使用一个开源项目,该项目有多个文件分布在多个文件夹中。我找到了每个程序的依赖关系,但无法弄清楚如何编译它们。

我的源代码分布在三个文件夹中。 一个)的模块 b)中的接口 c)中的子程序

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

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

对此有任何帮助表示赞赏。

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

    .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已经编译完毕。为什么在使可执行文件说未定义引用时出错?我错过了什么?

2 个答案:

答案 0 :(得分:6)

你可以做一个看似那样的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/和{{1}的根目录中编译源代码},你只需设置subroutines/就好了。

如果你有很多物品并且你不想手工编写所有物品,你可以使用以下技巧来检索它们

VPATH

Makefile中的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 $@ 命令允许您使用小丑wildcard;然后你只需要说明你将在*中检索的字符串,你想用$(SRCOBJ)替换.f90来获取模块的文件名。

答案 1 :(得分:3)

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

这可以分别使用-J-module gfortranifort标记来实现。