如何编译具有接口、模块和子例程的多文件夹 Fortran 项目 [英] how to compile multi-folder Fortran Project having interfaces, modules and subroutines

查看:9
本文介绍了如何编译具有接口、模块和子例程的多文件夹 Fortran 项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Fortran. I am working on a research project where I am using an open source project that has several files distributed in multiple folders. i found the dependency of each programs but could not figure out how to compile them.

我将源代码分布在三个文件夹中.a) 模块b) 接口c) 子程序

I have source code distributed in three folders. a)modules b)interfaces c)subroutines

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

I would like to run a program named as 'Main.f90' in subroutines folder, this program has dependency of source codes from modules and interfaces folders.

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

I am using eclipse for folder structure and makefile to compile.

对此的任何帮助表示赞赏.

Any help with this is appreciated.

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

UPDATE: I followed the answer posted by @MBR and @Stefan, for some reason VPATH did not able to find programs in source code so I explicitly gave path to those source folder in my Makefile. below is my make file script.

    .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

我编译了所有模块并放在根文件夹的模块目录中.所有编译都很顺利.构建可执行文件时出现错误.我收到以下错误.

I compiled all the modules and placed in Modules directory of root Folder. All compilation goes well. I get error when I build the executable. I get following error.

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

`iargc_' is being used in 'getdat file and iargc is already compiled. why there is error while making the executable saying undefined reference? what am I missing?

推荐答案

你可以做一个像这样的Makefile

You can do a Makefile which looks like that

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.

VPATH is the paths of the directories where your Makefile will look for source files, so if you compile your source in the root directory of modules/, interfaces/ and subroutines/, you just have to set up VPATH like that.

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

If you have many objects and you don't want to write everything by hand, you can retrieve them using the following trick

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

The wildcard command in a Makefile allows you to use a joker *; then you just have to say that in the strings you will retrieve in $(SRCOBJ), you want to substitute .f90 by .o to get the filenames of your modules.

这篇关于如何编译具有接口、模块和子例程的多文件夹 Fortran 项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆