make

From WikiROMS
Revision as of 00:26, 2 November 2006 by Kate (talk | contribs)
(change visibility) (diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This article first appeared in the HPC Newsletter.

Introduction to Make

Make is a tool which is almost as old as Unix, designed primarily for keeping track of how programs are compiled. That is what we will describe here, although it can be used for other things, including web page maintenance. It is just a matter of telling make what commands need to be run to update your files.

Make gets its instructions from a description file, by default named Makefile. This file is also called the Makefile, but other files can be used by invoking make with the -f option, e.g.:

make -f Makefile.yukon

When I first got our ocean model, its Makefile looked something like:

model: main.o init.o plot.o
<TAB> f90 -o model main.o init.o plot.o
main.o: main.f
<TAB> f90 -c -O main.f
init.o: init.f
<TAB> f90 -c -O init.f
plot.o: plot.f
<TAB> f90 -c -O0 plot.f
clean:
<TAB> rm *.o core

The default thing to build is "model", the first target. The syntax is:

target: dependencies
<TAB> command
<TAB> command

The target model depends on the object files, main.o and friends. They have to exist and be up to date before model's link command can be run. The other targets tell make how to create the object files. The original version of this Makefile turned off optimization on plot.f due to a compiler bug, but hopefully you won't ever have to worry about that.

Compiling model is simple, just type "make". Make will look for the file makefile or Makefile, read it, and do whatever is necessary to make model up to date. If you edit init.f, that file will be newer than init.o. Make would see that init.o is out of date and run the f90 -c -O init.f command. Now init.o is newer than model, so the link command f90 -o model main.o init.o plot.o must be executed.

Clean up by typing "make clean". The clean target will be brought up to date. clean has no dependencies, so the command rm *.o core will always be executed.

Macros

Make supports a simple string substitution macro. Set it with:

MY_MACRO = nothing today

and refer to it with:

$(MY_MACRO)

The convention is to put the macros near the top of your Makefile and to use upper case. Also, use separate macros for the name of your compiler and the flags it needs:

F90 = f90
F90FLAGS = -O3
LIBDIR = /usr/local/lib
LIBS = -L$(LIBDIR) -lmylib

Let's rewrite our Makefile using macros:

  1. IBM version
F90 = xlf90
F90FLAGS = -O3 -qstrict
LDFLAGS = -bmaxdata:0x40000000
model: main.o init.o plot.o
<TAB> $(F90) $(LDFLAGS) -o model main.o init.o plot.o
main.o: main.f
<TAB> $(F90) -c $(F90FLAGS) main.f
init.o: init.f
<TAB> $(F90) -c $(F90FLAGS) init.f
plot.o: plot.f
<TAB> $(F90) -c $(F90FLAGS) plot.f
clean:
<TAB> rm *.o core