use*_*314 6 fortran module gfortran subroutine multifile
我是Fortran的新手.我正在研究一个研究项目,我正在使用一个开源项目,该项目有多个文件分布在多个文件夹中.我发现每个程序的依赖性,但无法弄清楚如何编译它们.
我的源代码分布在三个文件夹中.a)模块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
Run Code Online (Sandbox Code Playgroud)
我编译了所有模块并放在根文件夹的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
Run Code Online (Sandbox Code Playgroud)
`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 $@
Run Code Online (Sandbox Code Playgroud)
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 $@
Run Code Online (Sandbox Code Playgroud)
wildcardMakefile中的命令允许你使用小丑*; 那么你就必须说,在你将检索的字符串$(SRCOBJ),要替换.f90的.o,让您的模块文件名.