
Documentation

To build everything important on the target system, assuming the file
"Makefile" is present, type:

	make

The Makefile is generated by a master makefile and a variety of config
files, all written in m4.  Typically a configure script interpreted by
/bin/sh is used to set everything up.  m4 is a preprocessor that is
standard on all unix systems.  There are in addition freely-distributable
versions of m4 available for non-Unix platforms (e.g. MS-DOS, VMS,
Amiga/Exec), such as PD m4 and GNU m4.

Unix like systems invariably support a version of "make" with certain
basic features.  See the SystemV reference manual for more information on
"standard" make.  At the present time, no enhancements to make (dependent
on the system) are supported by these makefile scripts.  But make
certainly needs some!  Supporting a package on multiple OS's and multiple
sites for multiple users is far too demanding a task for ordinary make
to handle well.  

As a result, many people now use alternatives to plain "make".  Perhaps
the most famous is "imake", because it is the standard tool for building
codes associated with the X consortium (the folks who bring us X-windows).
I have tried imake, and find its disadvantages almost as compelling as
its advantages.  This includes: 

  o	Many people find it difficult to learn
  o	It's not always available -- some systems that run X really do not 
	have imake by default.  You can in principle get the sources and
	compile it yourself, of course.
  o	The config files are not always correct, and this can be a lot
	of work to remedy.
  o	If the build procedure goes badly, forcing you to edit the
	generated makefile makefile directly, you will gain a new
	appreciation for the word "ugly".
  o	CPP (upon which imake is based) isn't particularly powerful.

Some other methods include using the GNU auto-configure script, or GNU
make.  The former does not really do what I need it to do, but GNU make
comes close.  At present all it is lacking is a bit more portability (it
does not port easily to some older SysV based machines, for example).

The scheme used here is to drive a number of scripts using m4 to create
a makefile.  These scripts are separated by utility as follows:

	makefile.m4	The controller.  
	cf_depend.m4	Contains all dependencies (optional, otherwise
			they go in makefile.m4).
	cf_basic.m4	Lots of preliminary macro definitions.
	cf_<pkg>.m4	A site & project specific config file.
	cf_unix.m4	Sets up make variables for Unix, given macro
			settings.  Handles compiler & linker flags,
			libraries, inclusion of system-specific config
			file, and all implicit rules.  
	cf_<sys>.m4	Config files for virtually every system I
			have experience with (and some I don't).

The only files that need to be changed for a particular project are
makefile.m4 and cf_<pkg>.m4, where <pkg> is some tag specific to the
application.  These deal essentially with ONLY the stuff specific
to the application, and are thus clean and the entire package easy
to maintain and use.

Further, the cf_<pkg>.m4 file may be soft linked from a standard location
(like ${configdir} or ${HOME}/config) into the build directory(s) by a
configure script.  Thus it can be refined for a particular site and always
found during the build, making maintenance and development over multiple
sites a breeze.  Once you determine what special flags and macro settings
are required on your system for the given app, you bury it in a config
file in ~/config and forget about it.  Also, the existence of only one
"master" copy of the build script ensures that changes to the dependency
lists are updated transparently on all systems.

To get the proper makefile, one needs to run makefile.m4 through m4 with
the appropriate macros defined.  For example:

	m4 -DDEBUG <makefile.m4 >makefile

(The input redirection is optional on most systems.)

Recognized options include:

	-DSYSTEM=<sys>	Specify system name (see note 1)
	-DDOUBLE	Compiles with double precision (see note 2)
	-DDEBUG		Compiles with debugging on
	-DOPT=<opt>	Specify optimization level (see note 3)
	-DWARN		Turn on compiler warnings
	-DPROF		Compiles with profiling on (if supported)
	-DGCC		Use gcc (see note 4)
	-DNO_X		Omit X linkage (see note 5)
	-DNO_TK		Omit Tcl/TK linkage (see note 5)
	-DNO_SHARE	Do not build shared libraries (see note 5)

If you are using a configure script the command line syntax will be
different.  Specifically, the configure script takes lower-case versions
of these, and all boolean switches can be specified as either on or off.
The default value may depend on the system.

------------------------------------------------------------------------------
Notes:

1. It is best if you use a configure script to set this automatically,
using the output of "uname".

2. These scripts are set up to expect that the double precision library
ends with a "d" (before the library suffix), the single precision library
with an "f".  On 32-bit machines, typically the single precision library
is built since this speeds development.  This is also simpler, since a
float (C) or REAL (Fortran) will usually be 32 bits.  By contrast, on a
Cray only the single precision libraries are built, since numerics are all
8 bytes.  Check the notes for your system to be sure.

3. On most platforms, optimization levels greater than 1 merely provide
the standard optimization.  But on some it will cause an optimizing
preprocessor and other time-consuming optimizations to be done (e.g.
HP-UX, AIX).  This is not always a good idea.  It may slow down
compilation by a factor of two or more with only a marginal speedup in
execution.  Sometimes, it may even produce bogus code.  So be sure you
know what you are doing.

4. The GNU compiler "gcc" is available on many systems, sometimes as the
default compiler and sometimes as an alternative.  Typically if there is a
vendor-supported ANSI compiler (e.g. c89 under HP-UX, acc under SunOS) that
will be used by default, hence the need for this flag.

5. All of the NO_<opt> flags are used to disable what is typically the
default behavior.  The default is to link against X and Tcl/TK if the
target system runs them, and to build shared libraries if supported (on
the target system and by the config file).  You must have enabled X and
Tcl/TK support by defining XWIN and TK, respectively, in cf_<pkg>.m4,
otherwise the NO_<opt> flag has no effect.

6. Some m4's do not handle the -D<macro-def> switch correctly.  In this
case I suggest installing GNU m4, as it installs easily (for me) and works
great.  Otherwise you can use the following trick to generate the makefile:

echo 'define(SYSTEM,BSD)' | cat - makefile.m4 | m4 > Makefile

------------------------------------------------------------------------------

There are many different "flavors" of Unix supported by these scripts.
Each OS has its own subtle characteristics, so be sure that the config
file being selected is appropriate for your system.  Some of these may not
work as advertised as I don't have access to all of these machines; in
that case please get it working and send the changes to me.  I've found
that most system-specific or site-specific needs can be satisfied by
modifying one of the existing make variables (see cf_<pkg>.m4 or
cf_unix.m4 for more info on what variables are available).  In addition,
this scheme may be adaptable to some non-Unix systems (e.g. Amiga) -- see
the appropriate sys/ directory for more info.

Bugs or other problem areas:
- Standard make does not recognize a dependency when there is
  trailing whitespace present in the dependency list.
- Using "~" (the csh symbol for your root directory) may not work from
  inside make, so avoid using it -- use $(HOME) instead.
- Sometimes a compile will fail but not remove the target object file,
  which will be incorrect or even empty.  In this case "make" will stop
  because of the error, but may never rebuild the object because it thinks
  it is up-to-date.  The clue that this has happened is strange error
  messages from the linker, such as being unable to find the desired object
  file even though it is clearly present.  In this case simply delete the
  offending object file and reinvoke make.


Maurice LeBrun
IFS, University of Texas
mjl@dino.ph.utexas.edu
