Makefiles -
08-17-2005
, 10:29 AM
It's a little difficult to fully explain Makefiles here, but here are
some of the basic rules:
* The make utility defaults to a certain set of rules; i.e., if you
have a shell program source file, say prog.sh, and type "make
prog" the make utility will automatically create "prog" and change
the mode so it is executable. This also holds for C and other
source files; make "knows" how to build an executable from a C
source code file.
* The make utility has never heard of Informix, so you need to
provide a set of rules make can use to compile 4/GL, ESQL/C, forms
and reports; you do this with a file, make.rules, that is included
in the top of your Makefile (it's attached to this message).
A Makefile defines targets -- prog, for example, is the target of
prog.sh -- and dependencies. A C program depends upon a object file, not
the source file (because make knows that compiling a .c results in a .o
which is then linked to produce an executable). So, you would define
targets like this:
MAKEFILE = Makefile
MAINS = prog cprog
OBJECTS = cprog.o
ALL: $(MAINS)
cprog: cprog.o
$(CC) $(CFLAGS) -s -o cprog cprog.o $(LDFLAGS)
cprog.o:
If you had prog.sh and cprog.c and Makefile in a directory, type make,
hit the return, and you wind up with prog and cprog, both of which are
executable.
Now, what if cprog has a couple of functions? OK, we add those like this:
OBJECTS = cprog.o func01.o func02.o
MAINS = cprog
ALL: $(MAINS)
cprog: cprog.o func01.o func02.o
$(CC) $(CFLAGS) -s -o cprog cprog.o func01.o func02.o $(LDFLAGS)
cprog.o:
func01.o:
func02.o:
and that's that.
CC, CFLAGS and LDFLAGS are tokens defined to mean something by make;
MAINS and OBJECTS are tokens defined locally (you'll see why we use
those later).
So, what about Informix stuff? Instead of saying that cprog above is
eprog instead?
MAKEFILE = Makefile
MAINS = prog eprog
OBJECTS = cprog.o func01.o func02.o
ALL: $(MAINS)
include /usr/local/include/make.rules
eprog: eprog.o func01.o func02.o
$(ESQL) $(ECFLAGS) -s -o eprog eprog.o func01.o func02.o $(LDFLAGS)
(the make.rules file below includes the instructions for make to use to
build an ESQL/C program)
You're asking about 4-GL, though and fglpc and the like -- well, the
make.rules file below includes the instructions for all of those, too;
the instructions in make.rules default to sformbuild, so you just (1)
change the FORM token in make.rules to
FORM = ${INFORMIXDIR}/bin/form4gl
or include the line above in your Makefile (what's in the Makefile
overrides what's in make.rules).
So your Makefile would look like:
MAKEFILE = Makefile
include /usr/local/include/make.rules
FORM = ${INFORMIXDIR}/bin/form4gl
FORMS = form1.frm form2.frm
ALL: $(FORMS)
and you'd get your forms built.
Notice something: there are blank lines between tokens and there are
tabs between tokens, the equals sign and the definition; there is also a
leading tab before $(CC) and $(ESQL) -- you separate with tabs and you
must have a leading tab to indent.
We do reports the same way we do the forms; i.e.,
REPORTS = rep01.arc rep02.arc
ALL: $(REPORTS)
You may want to change the definition of the report program in
make.rules -- we use ACE reports and that's the default we use.
In practice you'll have a mixture of MAINS, FORMS, REPORTS and the like;
use those tokens if you're going to use the make.rules file then tell
make to build them with
ALL: $(MAINS) $(FORMS) $(REPORTS)
Also notice in the above (and below) that tokens (in the Makefile and in
make.rules) are enclosed in parentheses and environment variables (like
LOGNAME, GRPNAME) are enclosed in braces -- that's not a hard-and-fast
rule, but it does help differentiate where some token definition comes from.
Hope this helps more than it hurts.
Here's a real Makefile that builds a couple of programs, junk, other,
subtab and testit for testing the fglgets function that comes with
Informix. It incorporates much of what's discussed above, plus a lot
more that we consider "standard" when building Makefiles (CVS tokens,
copyright notices, and a full set of definitions). Your mileage may vary.
#ident "$Id$"
#
# Name: $Source$
# Version: $Revision$
# Modified: $Date$
# Purpose:
# Author: trona
# Date: 03/05/03
# $Log$
#
# Generated by $Id$ Wed Mar 5 14:29:14 EST 2003
MAKEFILE = Makefile
BASDIR = ${INSTALL_BASE}
# These are the rules for making Informix targets:
include $(BASDIR)/include/make.rules
# Mess with them at your peril
CFLAGS = -xarch=native64 -xO3 -xautopar -xbuiltin=%all
-I${INFORMIXDIR}/incl/tools
OWNER = ${LOGNAME}
GROUP = ${GRPNAME}
BINDIR = $(BASDIR)/bin
BMASK = 0755
MAINS = junk other subtab testit
OBJECTS = fglgets.o junk.o other.o subtab.o tabfunc.o testit.o
SOURCES = fglgets.c other.4gl subtab.4gl tabfunc.c junk.4gl
testit.4gl
ALL: $(MAINS)
# Uncomment these if you are using the GNU Project RCS software
#SCCSDIR = fgl
#$(SOURCES):
# co $@
# Uncomment these if you are using the Berkeley sccs front end
software
#SCCSDIR = fgl
#$(SOURCES):
# sccs -d ${PROJECTDIR} -p $(SCCSDIR) get $(RELEASE) $@
junk: junk.o $(LIBRARY)
$(C4GL) $(C4FLAGS) -s -o junk junk.o $(LDFLAGS)
other: other.o fglgets.o $(LIBRARY)
$(C4GL) $(C4FLAGS) -s -o other other.o fglgets.o $(LDFLAGS)
subtab: subtab.o tabfunc.o $(LIBRARY)
$(C4GL) $(C4FLAGS) -s -o subtab subtab.o tabfunc.o $(LDFLAGS)
testit: testit.o fglgets.o $(LIBRARY)
$(C4GL) $(C4FLAGS) -s -o testit testit.o fglgets.o $(LDFLAGS)
fglgets.o:
tabfunc.o:
junk.o:
other.o:
subtab.o:
testit.o:
install: $(MAINS)
cp $(MAINS) $(BINDIR)
cd $(BINDIR);\
chown $(OWNER) $(MAINS);\
chgrp $(GROUP) $(MAINS);\
chmod $(BMASK) $(MAINS)
remove:
cd $(BINDIR);\
rm -f $(MAINS)
clean:
rm -f $(OBJECTS)
clobber:
rm -f $(OBJECTS) $(MAINS)
# sccs -d ${PROJECTDIR} -p $(SCCSDIR) clean
# rcsclean
newmakefile:
makefile -m -f $(MAKEFILE) \
'BASDIR = ${INSTALL_BASE}'
#ident "$Id: make.rules,v 4.6 2002/09/10 16:20:40 trona Exp $"
# Note: CFLAGS, C4FLAGS and ECFLAGS default to GCC; whichever
# token is LAST in this file will be used; i.e., if
# you're using Solaris, make sure the Solars CFLAGS,
# C4FLAGS and ECFLAGS are last (just swap the lines).
#
# $Log: make.rules,v $
# Revision 4.6 2002/09/10 16:20:40 trona
# add xbuiltin flag for Solaris
#
# Revision 4.5 2002/08/28 15:41:05 trona
# add -xautopar compiler option for Solaris
#
# Revision 4.4 2002/07/23 20:55:22 trona
# add native64 for Solaris
#
# Revision 4.3 2002/07/23 17:28:56 trona
# remove native flag for Solaris
#
# Revision 4.2 1997/12/22 13:21:56 jwats
# Removed duplicate .ec~ target.
#
# Revision 4.1 1997/08/24 15:56:29 trona
# Initial installation
#
..SUFFIXES: .arc .arc~ .ace .ace~ .cbl .cbl~ .frm .frm~ .per .per~ .o .4gl .4gl~ .4go .ec .ec~ .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~
# C optimization flag
# these are for Solaris
CFLAGS = -xarch=native64 -xO3 -xautopar -xbuiltin=%all
# these are for GCC
CFLAGS = -O3
# ace section
..ace~.arc:
$(GET) $(GFLAGS) $<
${INFORMIXDIR}/bin/saceprep $<
rm -f $*.ace
..ace.arc:
${INFORMIXDIR}/bin/saceprep $<
# perform section
FORM = ${INFORMIXDIR}/bin/sformbld
..per~.frm:
$(GET) $(GFLAGS) $<
${FORM} $<
rm -f $*.per
..per.frm:
${FORM} $<
# cobol language section
COBOL = cobol
CBFLAGS = -dn -WC,NOTRUNC,MESSAGE,SOURCE,COPY,CHECK,STD1(ASCII),N OCODECHK,NOALPHA
..cbl~:
$(GET) $(GFLAGS) $<
$(COBOL) $(CBFLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.cbl $*.lst $*.int
..cbl:
$(COBOL) $(CBFLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.lst $*.int $*.o
..cbl~.o:
$(GET) $(GFLAGS) $<
$(COBOL) $(CBFLAGS) -c $<
..cbl.o:
$(COBOL) $(CBFLAGS) -c $<
# 4gl language section
C4GL = c4gl
# 4/GL optimization flag
# These are for Solaris
C4FLAGS = -xarch=native64 -xO3 -xautopar -xbuiltin=%all -w
# These are for GCC
C4FLAGS = -O3
FGL = fglpc
..4gl~:
$(GET) $(GFLAGS) $<
$(C4GL) $(C4FLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.4gl $*.4ec $*.ec $*.[co]
..4gl:
$(C4GL) $(C4FLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.4ec $*.[co]
..4gl~.4go:
$(GET) $(GFLAGS) $<
$(FGL) $*.4gl
-rm -f $*.4gl
..4gl.4go:
$(FGL) $*.4gl
..4gl~.o:
$(GET) $(GFLAGS) $<
$(C4GL) $(C4FLAGS) -e $<
$(CC) $(C4FLAGS) -I${INFORMIXDIR}/incl/tools -c $*.c
-rm -f $*.4gl $*.4ec $*.ec $*.c
..4gl.o:
$(C4GL) $(C4FLAGS) -e $<
$(CC) $(C4FLAGS) -I${INFORMIXDIR}/incl/tools -c $*.c
-rm -f $*.4ec $*.ec $*.c
..4gl~.a:
$(GET) $(GFLAGS) $<
$(C4GL) $(C4FLAGS) -e $<
$(CC) $(C4FLAGS) -I${INFORMIXDIR}/incl/tools -c $*.c
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.4gl $*.4ec $*.ec $*.[co]
..4gl.a:
$(C4GL) $(C4FLAGS) -e $<
$(CC) $(C4FLAGS) -I${INFORMIXDIR}/incl/tools -c $*.c
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.4ec $*.ec $*.[co]
# esql/c language section
ESQL = esql
# ESQL/C optimization flags
# These are for Solaris
ECFLAGS = -xarch=native64 -xO3 -xautopar -xbuiltin=%all
# These are for GCC
ECFLAGS = -O3
..ec~:
$(GET) $(GFLAGS) $<
$(ESQL) $(ECFLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.ec $*.[co]
..ec:
$(ESQL) $(ECFLAGS) -s -o $@ $< $(LDFLAGS)
-rm -f $*.[co]
..ec~.o:
$(GET) $(GFLAGS) $<
$(ESQL) $(ECFLAGS) -e $<
$(CC) -I${INFORMIXDIR}/incl/esql $(ECFLAGS) -c $*.c
-rm -f $*.ec $*.c
..ec.o:
$(ESQL) $(ECFLAGS) -e $<
$(CC) -I${INFORMIXDIR}/incl/esql $(ECFLAGS) -c $*.c
-rm -f $*.c
..ec~.a:
$(GET) $(GFLAGS) $<
$(ESQL) $(ECFLAGS) -e $<
$(CC) -I${INFORMIXDIR}/incl/esql $(ECFLAGS) -c $*.c
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.ec $*.[co]
..ec.a:
$(ESQL) $(ECFLAGS) -e $<
$(CC) -I${INFORMIXDIR}/incl/esql $(ECFLAGS) -c $*.c
$(AR) $(ARFLAGS) $@ $*.o
-rm -f $*.[co]
..c~.c:
$(GET) $(GFLAGS) $<
..c~.o:
$(GET) $(GFLAGS) $<
$(CC) $(CFLAGS) -c $*.c
-rm -f $*.c
# RCS section
CO = co
..ace,v.arc:
$(CO) $<
$(INFORMIXDIR)/bin/saceprep $<
..per,v.frm:
$(CO) $<
$(FORM) $<
..ec,v.o:
$(CO) $<
$(ESQL) $(ECFLAGS) -c $*.o
-rm -f $*.c
..4gl,v.o:
$(CO) $<
$(C4GL) $(C4FLAGS) -c $*.o
-rm -f $*.c
..c,v.o:
$(CO) $<
$(CC) $(CFLAGS) -c $*.o
-rm -f $*.c
..ec,v.ec:
$(CO) $<
..4gl,v.4gl:
$(CO) $<
..c,v.c:
$(CO) $< |