Could someone share a Makefile using gfortran + openmpi on Windows, Linux and Mac? Thanks!

Dear all,

I wonder, could someone if possible please share a Makefile with gfortran + openmpi on Windows, Linux and Mac?
Just curious how to specify the mpi library.
Thank you very much indeed in advance! Sorry this is a lazy question but I just asked, LOL.

I usually use intel OneAPI with MPI on windows and linux. On Linux the intel’s Makefile is simple, you do not need to specify any library. Just plug in and play.
On Windows it is a little tricky, however I managed to use Makefile for Intel OneAPI with MPI on Windows, here I share my Makefile, hopefully it may be helpful for some guys,
On windows, I write a bat file like below, so it will call intel’s environment first,

@echo off
:: cls
setlocal
cd /d "%~dp0"  
::  cd /d "%~dp0"  is not really needed, can be commentted.
call setvars.bat
:: make clean -f Makefile.win
make -f Makefile.win

I run this bat, and this bat run my Makefile.win file as below,

# My Makefile.win file

#MPI=false
MPI=true

ifeq ($(MPI),true)
FC = ifort.exe
MPIFILE=mympi
EXEC = rpem_mpi.exe
LINKER = /link

IDIR = 
FFLAGS=/nologo /MP /O3 /QxHost /Qipo /libs:static /threads /Qmkl:cluster /debug:full /traceback # /assume:buffered_io /heap-arrays0
F77FLAGS=$(FFLAGS)  # intel fortran  
LDFLAGS=/INCREMENTAL:NO /LARGEADDRESSAWARE /LIBPATH:"C:\Program Files (x86)\Intel\oneAPI\mpi\latest\lib\release" #/IMPLIB: "C:\Program Files (x86)\Intel\oneAPI\mpi\latest\lib\release\impi.lib"
LIBS="C:\Program Files (x86)\Intel\oneAPI\mpi\latest\lib\release\impi.lib"

else
FC = ifort.exe
MPIFILE=nompi
EXEC = rpem.exe
LINKER = /link

IDIR = 
FFLAGS=/nologo /MP /O3 /QxHost /Qipo /libs:static /threads /Qmkl:cluster /debug:full /traceback # /assume:buffered_io /heap-arrays0
F77FLAGS=$(FFLAGS)  # intel fortran  
LDFLAGS=/INCREMENTAL:NO /LARGEADDRESSAWARE 
LIBS=
endif


.SUFFIXES:
.SUFFIXES: .obj .f .f90

.f90.obj:
	$(FC) $(FFLAGS) /c $<

%.obj: %.mod

OBJECTS=\
EM_mix.obj\
analysis.obj\
constants.obj\
formats.obj\
mixture.obj\
model.obj\
$(MPIFILE).obj\
ran.obj\
reader.obj\
step.obj\
time.obj\
FLINT.obj\
FLINT_base.obj\
FLINTUtils.obj\
ERK.obj\
ERKInit.obj\
ERKIntegrate.obj\
ERKInterp.obj\
ERKStepInt.obj\
ButcherTableaus.obj\
MyDiffEq.obj\
StepSz.obj\
dvode_f90_m.obj\
dvode_solver.obj\
lapack.obj\
opkdmain.obj\
opkda1.obj\
opkda2.obj\
odex.obj\
ogpf.obj\
radau.obj\
dc_lapack.obj\
lapackc.obj\
radau5.obj\
rkc.obj\
rock2.obj\
rock4.obj\
rodas.obj\
seulex.obj


   
EM_mix: $(OBJECTS)
	$(FC) /exe:$(EXEC) $(OBJECTS) $(LIBS) $(LINKER) /out:$(EXEC) $(LDFLAGS) 

clean:
	@del /q /f $(EXEC) *.mod *.obj *~ > nul 2> nul
# not that in windows rm -f does not work, so use del instead. 
# > nul 2> nul just to suppress some redundunt mesage.


EM_mix.obj: constants.obj ran.obj mixture.obj step.obj model.obj time.obj formats.obj MyDiffEq.obj\
	$(MPIFILE).obj ogpf.obj analysis.obj EM_mix.f90
	$(FC) $(FFLAGS) /c EM_mix.f90

analysis.obj: constants.obj analysis.f90
	$(FC) $(FFLAGS) /c analysis.f90
	
constants.obj: constants.f90
	$(FC) $(FFLAGS) /c constants.f90
	
formats.obj: constants.obj formats.f90
	$(FC) $(FFLAGS) /c formats.f90

mixture.obj: constants.obj mixture.f90
	$(FC) $(FFLAGS) /c mixture.f90

model.obj: constants.obj FLINT.obj MyDiffEq.obj dvode_solver.obj model.f90
	$(FC) $(FFLAGS) /c model.f90
	
$(MPIFILE).obj: $(MPIFILE).f90
	$(FC) $(FFLAGS) /heap-arrays0 -c $(MPIFILE).f90
	
ran.obj: ran.f90
	$(FC) $(FFLAGS) /heap-arrays0 /c ran.f90
	
reader.obj: constants.obj $(MPIFILE).obj reader.f90
	$(FC) $(FFLAGS) /c reader.f90
	
step.obj: constants.obj mixture.obj formats.obj reader.obj model.obj\
	MyDiffEq.obj dvode_solver.obj analysis.obj $(MPIFILE).obj step.f90
	$(FC) $(FFLAGS) /heap-arrays0 /c step.f90	

time.obj: constants.obj time.f90
	$(FC) $(FFLAGS) /c time.f90
	
MyDiffeq.obj: FLINT.obj MyDiffeq.f90
	$(FC) $(FFLAGS) /c MyDiffeq.f90

FLINT.obj: FLINT_base.obj ERK.obj FLINT.f90
	$(FC) $(FFLAGS) /c FLINT.f90

FLINT_base.obj: FLINTUtils.obj FLINT_base.f90
	$(FC) $(FFLAGS) /c FLINT_base.f90
	
FLINTUtils.obj: FLINTUtils.f90
	$(FC) $(FFLAGS) /c FLINTUtils.f90

ERK.obj: FLINT_base.obj ButcherTableaus.obj StepSz.obj ERK.f90
	$(FC) $(FFLAGS) /c ERK.f90
	
ERKInit.obj: ERK.obj ERKInit.f90
	$(FC) $(FFLAGS) /c ERKInit.f90	
	
ERKIntegrate.obj: ERK.obj ERKIntegrate.f90
	$(FC) $(FFLAGS) /c ERKIntegrate.f90
	
ERKInterp.obj: ERK.obj ERKInterp.f90
	$(FC) $(FFLAGS) /c ERKInterp.f90	
	
ERKStepInt.obj: ERK.obj ERKStepInt.f90
	$(FC) $(FFLAGS) /c ERKStepInt.f90
	
ButcherTableaus.obj: FLINT_base.obj ButcherTableaus.f90
	$(FC) $(FFLAGS) /c ButcherTableaus.f90

StepSz.obj: FLINT_base.obj StepSz.f90
	$(FC) $(FFLAGS) /c StepSz.f90
	
dvode_f90_m.obj: dvode_f90_m.f90
	$(FC) $(FFLAGS) /c dvode_f90_m.f90

dvode_solver.obj: constants.obj MyDiffeq.obj dvode_f90_m.obj dvode_solver.f90
	$(FC) $(FFLAGS) /c dvode_solver.f90
	
lapack.obj: lapack.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c lapack.f
	
opkdmain.obj: opkdmain.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c opkdmain.f

opkda1.obj: opkda1.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c opkda1.f	

opkda2.obj: opkda2.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c opkda2.f	
	
odex.obj: odex.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c odex.f	
	
ogpf.obj: ogpf.f90
	$(FC) $(FFLAGS) /c ogpf.f90

radau.obj: radau.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c radau.f
	
dc_lapack.obj: dc_lapack.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c dc_lapack.f
	
lapackc.obj: lapackc.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c lapackc.f
	
radau5.obj: radau5.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c radau5.f
	
rkc.obj: rkc.f
	$(FC) $(F77FLAGS) /c rkc.f
	
rock2.obj: rock2.f
	$(FC) $(F77FLAGS) /c rock2.f
	
rock4.obj: rock4.f
	$(FC) $(F77FLAGS) /c rock4.f
	
rodas.obj: rodas.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c rodas.f

seulex.obj: seulex.f
	$(FC) $(F77FLAGS) /warn:nointerfaces /c seulex.f

If someone have better idea how to do Makefile on Windows using Intel OneAPI and MPI, or gfortran + openmpi, please also let me know thanks!

Not sure if my comment will be of much help, but the way I have seen Makefiles being used for true cross-platform project configuration and compilation is slightly more involved. At least if you don’t want to be extremely explicit in how you write your Makefiles.

Basically people use Automake and Autoconf. You write a Makefile.am which automake uses to generate a Makefile.in. The *.in files are then used by autoconf to generate the final Makefile. A similar process is followed with the configure file.

An alternative to the GNU Autotools suite is CMake, which similarly, will generate your Makefiles for every supported OS. IMO it is easier to write CMake files that Autoconf/Automake files.

An example of a project that uses both Automake and CMake is HDF5. You can download the source code and have a peak (you will need to make an account), although I suspect it won’t be of much help.

That is the easiest way that I know for cross-platform compilation. Take what I have written with a grain of salt since it has been more than 3 years since I had to worry about Autoconf or CMake.

1 Like