[Next] [Previous] [Up] [Top] [Contents] [Index]

Appendix I. Programming Examples

I.2 Makefiles and the make Process

I.2.1 A Simple make Process

Our "Hello World" example is quite simple, and illustrates many of the features we have discussed in Chapter 17. First we'll run a file listing to see the files that are involved:

-rw-r--r--   1 aheavey  g020         515 Dec 20 16:27 Makefile
-rw-r--r--   1 aheavey  g020          91 Dec 20 16:27 mcprog.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model1.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model2.f

The contents of the FORTRAN source files that will be used as required files follows:

<fsui01> cat mcprog.f
      WRITE (*,*) ' Hello world '
      CALL MODEL1
      CALL MODEL2
      STOP
      END

<fsui01> cat model1.f
      SUBROUTINE MODEL1
      WRITE (*,*) ' Hello from MODEL 1 '
      RETURN
      END

<fsui01> cat model2.f
      SUBROUTINE MODEL2
      WRITE (*,*) ' Hello from MODEL 2 '
      RETURN
      END

Our Makefile illustrates the use of macro definitions, iterative target defintions, the use of a library in addition to other required files, comment lines, and macro expansion (described in the man pages). It provides two levels of "housekeeping" at the end, clean to remove just the "stray" files, and clobber, which gets rid of all resulting files thus allowing you to run make again under the same initial conditions.

<fsui01> cat Makefile
# use /bin/sh within make
SHELL = /bin/sh

#   Standard FORTRAN command and flags
F77    = f77
FFLAGS = -O2

# Build the 'mcprog' program from mcprog.f and libmc.a
mcprog   : mcprog.f   libmc.a ; $(F77) $(FFLAGS) -o mcprog mcprog.f libmc.a

# Move any missing modules into libmc.a
libmc.a  : model1.o  model2.o ; ar -r libmc.a $(?)

# Compile missing or out-of-date modules
model1.o : model1.f ;     $(F77) $(FFLAGS) -c $(?)

model2.o : model2.f ;     $(F77) $(FFLAGS) -c $(?)

clean    : ; rm -f *.o

clobber : ; rm -f *.o ; rm -f mcprog ; rm -f libmc.a

Run make without specifying a target, and it will use the first target it encounters, mcprog. Notice that make displays its progress on the screen, creating the library libmc.a prior to building the executable mcprog:

<fsui01> make
f77 -O2 -c model1.f model1.f
model1.f:
        model1:
model1.f:
        model1:
f77 -O2 -c model2.f model2.f
model2.f:
        model2:
model2.f:
        model2:
ar -r libmc.a model1.o model2.o
ar: creating libmc.a
f77 -O2 -o mcprog mcprog.f libmc.a
mcprog.f:
 MAIN:

Run another file listing to see that our target and some intermediate files were created:

-rwxr-xr-x   1 aheavey  g020       13452 Dec 20 16:34 mcprog*
-rw-r--r--   1 aheavey  g020        2712 Dec 20 16:34 libmc.a
-rw-r--r--   1 aheavey  g020        1248 Dec 20 16:34 model2.o
-rw-r--r--   1 aheavey  g020        1248 Dec 20 16:34 model1.o
-rw-r--r--   1 aheavey  g020          91 Dec 20 16:27 mcprog.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model2.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model1.f
-rw-r--r--   1 aheavey  g020         515 Dec 20 16:27 Makefile

Run the executable, mcprog:

<fsui01> mcprog
  Hello world
  Hello from MODEL 1
  Hello from MODEL 2

Run make clean to remove the object files:

<fsui01> make clean
rm -f *.o

A directory listing shows the object files were deleted:

-rwxr-xr-x   1 aheavey  g020       13452 Dec 20 16:34 mcprog*
-rw-r--r--   1 aheavey  g020        2712 Dec 20 16:34 libmc.a
-rw-r--r--   1 aheavey  g020          91 Dec 20 16:27 mcprog.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model2.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model1.f
-rw-r--r--   1 aheavey  g020         515 Dec 20 16:27 Makefile

Finally, run make clobber to remove all the created files:

<fsui01> make clobber
rm -f *.o ; rm -f mcprog ; rm -f libmc.a

... and check the final directory listing, which should match the original one:

-rw-r--r--   1 aheavey  g020         515 Dec 20 16:27 Makefile
-rw-r--r--   1 aheavey  g020          91 Dec 20 16:27 mcprog.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model1.f
-rw-r--r--   1 aheavey  g020          88 Dec 20 16:27 model2.f

I.2.2 A Physics Makefile

The following is an example physics Makefile with FORTRAN and C sources.

###############
#   MACROS    #
###############

# Always force the shell to be /bin/sh, for portability

SHELL=/bin/sh

# some variables come from the environment existing when make is run

#    CRNLIB       (from 'setup cern')
#    HISTO_DIR    (from 'setup histo')
#    MCFAST_DIR   (a group library from 'source ~bphyslib/mcfast/mcenv')
#    MCFIO_DIR    (a group library from 'source ~bphyslib/mcfast/mcenv')

# macros for directories containing INCLUDE files:

INC1 = $(MCFAST_DIR)/inc/event
INC2 = $(STDHEP_INC)

# macro for MCFAST object library directory

LIB = $(MCFAST_DIR)/lib.IRIX

# macro listing all USER object routines

OBJS  = \
  usr_analysis.o \
  usr_before_trigger.o \
  assign_off_mass.o \
  costh.o \
  fin_init.o \
  find_b_psiks.o

# macros for object libraries from products HISTO and CERN

HISTLIB = $(HISTO_DIR)/lib/libFHistoHB.a
PACKLIB = $(CRNLIB)/libpacklib.a 
MATHLIB = $(CRNLIB)/libmathlib.a 
KERNLIB = $(CRNLIB)/libkernlib.a 

# macro for the SGI exception handler library

FP_EXCEPTION = /usr/lib/libfpe.a

# macro for all linked libraries

LOADLIBS= \
  $(LIB)/libgen.a      \
  $(LIB)/libdatafile.a \
  $(LIB)/libio.a       \
  $(LIB)/libutil.a     \
  $(MCFIO_DIR)/lib.IRIX/libFmcfio.a \
  $(HISTLIB) \
  $(PACKLIB) \
  $(MATHLIB) \
  $(KERNLIB) \
  $(FP_EXCEPTION)

# macros for compiler option flags

CFLAGS = -g
FFLAGS = -g -I$(INC1) -I$(INC2)

###############
#   TARGETS   #
###############

# f77 is used to run the link editor here.
# FORTRAN and C compilation is done via the rules defined below.

mcfast: $(OBJS) $(LOADLIBS); f77 -o mcfast $(OBJS) $(LOADLIBS)

###############
#  SUFFIXES   #
###############

# You must list all suffixes used in this Makefile's rules

.SUFFIXES : .c .F .f .o

###############
#    RULES    #
###############

# RULES for building *.o files from *.f or *.c

#     The $? internal macro expands to the list of *.f or *.c files which are
#     newer than their corresponding *.o file.

#     Macros CFLAGS and FFLAGS are defined above with compiler options

.f.o: ; f77 -c $(FFLAGS) $?

.c.o: ; cc  -c $(CFLAGS) $?


UNIX at Fermilab - 10 Apr 1998

[Next] [Previous] [Up] [Top] [Contents] [Index]