Optimizing Makefile for LHS Code in Fortran

  • Context: Fortran 
  • Thread starter Thread starter swartzism
  • Start date Start date
  • Tags Tags
    Code Fortran
Click For Summary

Discussion Overview

The discussion focuses on optimizing a Makefile for a Latin Hypercube sampling code written in Fortran, which consists of approximately 80 functions and subroutines. Participants explore various methods to streamline the Makefile, aiming for a more efficient and manageable structure.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant expresses the challenge of creating a lengthy Makefile due to the number of subroutines and seeks a more efficient approach.
  • Another participant suggests a simplified version of the Makefile using pattern rules, but questions why it does not work as intended.
  • A later reply indicates that the simplified Makefile makes the participant's life easier, suggesting a positive reception to the proposed changes.
  • Further contributions propose an even more succinct method using GNU Make features to automatically generate the object file list from the Fortran source files in the directory.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the effectiveness of the proposed Makefile optimizations, as some methods are questioned while others are praised. The discussion remains open with multiple competing views on how to best structure the Makefile.

Contextual Notes

Some participants rely on specific assumptions about the use of GNU Make and the presence of all necessary .F90 files in the directory, which may limit the applicability of their suggestions.

swartzism
Messages
103
Reaction score
0
I've always made my own makefiles and it hasn't been an issue because it's usually a small number of subroutines. However, I am working on modernizing and optimizing a Latin Hypercube sampling code in Fortran which has close to 80 functions/subroutines that I am splitting up into different files and putting in a Makefile. This is pretty tedious and makes for a pretty long Makefile in the style that I've always used. My question is this: is there a slicker, prettier, better, etc. way to do this?

Code:
# Start of the makefile

# Defining variables
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

# Makefile
LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
lhs.o: lhs.F90
    $(FC) -c $(FCFLAGS) lhs.F90
chkstr.o: chkstr.F90
    $(FC) -c $(FCFLAGS) chkstr.F90
chkdim.o: chkdim.F90
    $(FC) -c $(FCFLAGS) chkdim.F90
chkdat.o: chkdat.F90
    $(FC) -c $(FCFLAGS) chkdat.F90
betaln.o: betaln.F90
    $(FC) -c $(FCFLAGS) betaln.F90
betaic.o: betaic.F90
    $(FC) -c $(FCFLAGS) betaic.F90
betafn.o: betafn.F90
    $(FC) -c $(FCFLAGS) betafn.F90
beta.o: beta.F90
    $(FC) -c $(FCFLAGS) beta.F90
banner.o: banner.F90
    $(FC) -c $(FCFLAGS) banner.F90
chktri.o: chktri.F90
    $(FC) -c $(FCFLAGS) chktri.F90
chkzro.o: chkzro.F90
    $(FC) -c $(FCFLAGS) chkzro.F90
chlsky.o: chlsky.F90
    $(FC) -c $(FCFLAGS) chlsky.F90
cmcrd.o: cmcrd.F90
    $(FC) -c $(FCFLAGS) cmcrd.F90
corcal.o: corcal.F90
    $(FC) -c $(FCFLAGS) corcal.F90
corout.o: corout.F90
    $(FC) -c $(FCFLAGS) corout.F90
datout.o: datout.F90
    $(FC) -c $(FCFLAGS) datout.F90
datsqz.o: datsqz.F90
    $(FC) -c $(FCFLAGS) datsqz.F90
dmfsd.o: dmfsd.F90
    $(FC) -c $(FCFLAGS) dmfsd.F90
dsinv.o: dsinv.F90
    $(FC) -c $(FCFLAGS) dsinv.F90
errchk.o: errchk.F90
    $(FC) -c $(FCFLAGS) errchk.F90
errget.o: errget.F90
    $(FC) -c $(FCFLAGS) errget.F90
errprt.o: errprt.F90
    $(FC) -c $(FCFLAGS) errprt.F90
erstgt.o: erstgt.F90
    $(FC) -c $(FCFLAGS) erstgt.F90
erxset.o: erxset.F90
    $(FC) -c $(FCFLAGS) erxset.F90
fdump.o: fdump.F90
    $(FC) -c $(FCFLAGS) fdump.F90
findit.o: findit.F90
    $(FC) -c $(FCFLAGS) findit.F90
finver.o: finver.F90
    $(FC) -c $(FCFLAGS) finver.F90
finvnor.o: finvnor.F90
    $(FC) -c $(FCFLAGS) finvnor.F90
histo.o: histo.F90
    $(FC) -c $(FCFLAGS) histo.F90
hpsrt.o: hpsrt.F90
    $(FC) -c $(FCFLAGS) hpsrt.F90
hstout.o: hstout.F90
    $(FC) -c $(FCFLAGS) hstout.F90
hypgeo.o: hypgeo.F90
    $(FC) -c $(FCFLAGS) hypgeo.F90
i1mach.o: i1mach.F90
    $(FC) -c $(FCFLAGS) i1mach.F90
imtql2.o: imtql2.F90
    $(FC) -c $(FCFLAGS) imtql2.F90
j4save.o: j4save.F90
    $(FC) -c $(FCFLAGS) j4save.F90
matinv.o: matinv.F90
    $(FC) -c $(FCFLAGS) matinv.F90
mix.o: mix.F90
    $(FC) -c $(FCFLAGS) mix.F90
normal.o: normal.F90
    $(FC) -c $(FCFLAGS) normal.F90
onechk.o: onechk.F90
    $(FC) -c $(FCFLAGS) onechk.F90
outcrd.o: outcrd.F90
    $(FC) -c $(FCFLAGS) outcrd.F90
outdat.o: outdat.F90
    $(FC) -c $(FCFLAGS) outdat.F90
pmtrx.o: pmtrx.F90
    $(FC) -c $(FCFLAGS) pmtrx.F90
posdef.o: posdef.F90
    $(FC) -c $(FCFLAGS) posdef.F90
pythag.o: pythag.F90
    $(FC) -c $(FCFLAGS) pythag.F90
r1mach.o: r1mach.F90
    $(FC) -c $(FCFLAGS) r1mach.F90
ranker.o: ranker.F90
    $(FC) -c $(FCFLAGS) ranker.F90
rdpar.o: rdpar.F90
    $(FC) -c $(FCFLAGS) rdpar.F90
rierfc1.o: rierfc1.F90
    $(FC) -c $(FCFLAGS) rierfc1.F90
s88fmt.o: s88fmt.F90
    $(FC) -c $(FCFLAGS) s88fmt.F90
setdef.o: setdef.F90
    $(FC) -c $(FCFLAGS) setdef.F90
sift.o: sift.F90
    $(FC) -c $(FCFLAGS) sift.F90
sspev.o: sspev.F90
    $(FC) -c $(FCFLAGS) sspev.F90
tqlrat.o: tqlrat.F90
    $(FC) -c $(FCFLAGS) tqlrat.F90
trbak3.o: trbak3.F90
    $(FC) -c $(FCFLAGS) trbak3.F90
tred3.o: tred3.F90
    $(FC) -c $(FCFLAGS) tred3.F90
triang.o: triang.F90
    $(FC) -c $(FCFLAGS) triang.F90
unifrm.o: unifrm.F90
    $(FC) -c $(FCFLAGS) unifrm.F90
vif.o: vif.F90
    $(FC) -c $(FCFLAGS) vif.F90
wrtcrd.o: wrtcrd.F90
    $(FC) -c $(FCFLAGS) wrtcrd.F90
wrtpar.o: wrtpar.F90
    $(FC) -c $(FCFLAGS) wrtpar.F90
xerabt.o: xerabt.F90
    $(FC) -c $(FCFLAGS) xerabt.F90
xerctl.o: xerctl.F90
    $(FC) -c $(FCFLAGS) xerctl.F90
xerprt.o: xerprt.F90
    $(FC) -c $(FCFLAGS) xerprt.F90
xerror.o: xerror.F90
    $(FC) -c $(FCFLAGS) xerror.F90
xerrwv.o: xerrwv.F90
    $(FC) -c $(FCFLAGS) xerrwv.F90
xersav.o: xersav.F90
    $(FC) -c $(FCFLAGS) xersav.F90
xgetua.o: xgetua.F90
    $(FC) -c $(FCFLAGS) xgetua.F90
usrdst.o: usrdst.F90
    $(FC) -c $(FCFLAGS) usrdst.F90
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

# Cleaning everything
clean:
    rm $(OBJ)

# End of the makefile
 
Technology news on Phys.org
This on its own:
Code:
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o \
      banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o \
      datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o \
      erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o \
      hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o \
      outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o \
      rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o \
      triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o \
      xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

.PHONY: clean
clean:
    rm $(OBJ)
doesn't work?
 
Last edited:
Learn something new every day! This makes my life a lot simpler.
 
wle said:
This on its own:
Code:
OBJ = lhs.o chkstr.o chkdim.o chkdat.o betaln.o betaic.o betafn.o beta.o \
      banner.o chktri.o chkzro.o chlsky.o cmcrd.o corcal.o corout.o \
      datout.o datsqz.o dmfsd.o dsinv.o errchk.o errget.o errprt.o erstgt.o \
      erxset.o fdump.o findit.o finver.o finvnor.o histo.o hpsrt.o hstout.o \
      hypgeo.o i1mach.o imtql2.o j4save.o matinv.o mix.o normal.o onechk.o \
      outcrd.o outdat.o pmtrx.o posdef.o pythag.o r1mach.o ranker.o rdpar.o \
      rierfc1.o s88fmt.o setdef.o sift.o sspev.o tqlrat.o trbak3.o tred3.o \
      triang.o unifrm.o vif.o wrtcrd.o wrtpar.o xerabt.o xerctl.o xerprt.o \
      xerror.o xerrwv.o xersav.o xgetua.o usrdst.o
FC = ifort
FCFLAGS = -O3

LHS: $(OBJ)
    $(FC) -o LHS $(FCFLAGS) $(OBJ)
%.o: %.F90
    $(FC) -c $(FCFLAGS) $<

.PHONY: clean
clean:
    rm $(OBJ)
doesn't work?

This can be written even more succinctly, assuming gnu make and assuming every .F90 file in the directory is to be compiled:
Code:
OBJ := $(patsubst %.F90,%.o,$(wildcard *.F90))
FC = ifort
FCFLAGS = -O3
# Remainder remains the same
 
D H said:
This can be written even more succinctly, assuming gnu make and assuming every .F90 file in the directory is to be compiled:
Code:
OBJ := $(patsubst %.F90,%.o,$(wildcard *.F90))
FC = ifort
FCFLAGS = -O3
# Remainder remains the same

Very cool.
 

Similar threads

  • · Replies 34 ·
2
Replies
34
Views
5K