Fortran Optimizing Makefile for LHS Code in Fortran

  • Thread starter Thread starter swartzism
  • Start date Start date
  • Tags Tags
    Code Fortran
AI Thread Summary
The discussion centers around optimizing a Makefile for a Fortran project involving a Latin Hypercube sampling code with approximately 80 functions and subroutines. The original Makefile was lengthy and tedious to manage, prompting the inquiry for a more efficient solution. A more streamlined approach was suggested, utilizing GNU Make features such as wildcard and pattern substitution functions. This allows for automatic generation of object file lists from the source files in the directory, significantly simplifying the Makefile structure. The revised method enhances maintainability and reduces redundancy, making the build process more efficient.
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.
 
Dear Peeps I have posted a few questions about programing on this sectio of the PF forum. I want to ask you veterans how you folks learn program in assembly and about computer architecture for the x86 family. In addition to finish learning C, I am also reading the book From bits to Gates to C and Beyond. In the book, it uses the mini LC3 assembly language. I also have books on assembly programming and computer architecture. The few famous ones i have are Computer Organization and...
What percentage of programmers have learned to touch type? Have you? Do you think it's important, not just for programming, but for more-than-casual computer users generally? ChatGPT didn't have much on it ("Research indicates that less than 20% of people can touch type fluently, with many relying on the hunt-and-peck method for typing ."). 'Hunt-and-peck method' made me smile. It added, "For programmers, touch typing is a valuable skill that can enhance speed, accuracy, and focus. While...
I had a Microsoft Technical interview this past Friday, the question I was asked was this : How do you find the middle value for a dataset that is too big to fit in RAM? I was not able to figure this out during the interview, but I have been look in this all weekend and I read something online that said it can be done at O(N) using something called the counting sort histogram algorithm ( I did not learn that in my advanced data structures and algorithms class). I have watched some youtube...

Similar threads

Replies
34
Views
4K
Back
Top