How to compile a Fortran project with multiple folders with interfaces, modules, and routines

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

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

I would like to run a program called "Main.f90" in the subprograms folder, this program has a source code dependency on modules and interface folders.

I use eclipse for folder structure and makefile for compilation.

Any help with this is appreciated.

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

.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 put them in the Modules directory of the root folder. The whole compilation is going well. I get an error while creating an executable file. I get the 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_ 'is used in the' getdat file, and iargc is already compiled. why does an error occur when creating an executable saying an undefined link? What am I missing?

+6
source share
2 answers

You can make a makefile that looks like this

 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 are directory paths in which your Makefile will search for source files, so if you compile the source code in the root directory of modules/ , interfaces/ and subroutines/ , you just need to configure VPATH .

If you have many objects and don’t want to write everything manually, you can get 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 $@ 

The wildcard command in the Makefile allows you to use the joker * ; then you just need to say that in the lines you get in $(SRCOBJ) , you want to replace .f90 with .o to get the file names of your modules.

+6
source

You can create your Makefiles as usual. The biggest problem should be .mod files. The simplest solution to this problem is to create a separate folder in which these files are stored and searched.

This can be achieved using the -J and -module flags for -J and ifort respectively.

+3
source

Source: https://habr.com/ru/post/952585/


All Articles