Makefiles
Posted in 2005
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 @