##
##  smake.pod -- Smake Documentation in Plain Old Document (POD) Format
##  Copyright (c) 1994-1999 Ralf S. Engelschall, All Rights Reserved. 
##

=head1 NAME

SMake - Makefile generator

=head1 VERSION

@V@

=head1 SYNOPSIS

B<smake>
[B<-I> I<directory>|I<pathlist>]
[B<-o> I<outputfile>]
[B<-x>]
[B<-V>]
[B<-h>]
I<smakefile>

B<smkmf>
[B<-I> I<directory>|I<pathlist>]
[B<-a>]
[B<-q>]
[B<-V>]
[B<-h>]
[I<directory>]

=head1 DESCRIPTION

B<SMake> is a powerful mechanism to generate standard F<Makefile>s out of
skeleton F<Makefile>s which only provide the essential parts.  The missing
stuff gets automatically filled in by shared include files. A great scheme to
create a huge Makefile hierarchy and to keep it consistent for the time of
development.  The trick is that it merges the skeleton (F<SMakefile>) and the
templates (Include files) in a priority-driven way, i.e. defines and targets
can be overwritten. The idea is taken from X Consortiums B<Imake>, but the
goal here is not inherited system independence for the Makefiles, the goal is
consistency and power without the need of manually maintaining a Makefile
hierarchy consisting of plain Makefiles. 

Notice that B<SMake> is a Makefile I<generator>, not an I<evaluator> like
F<make>, i.e. it generates standard Makefiles at development which are later
evaluated by the standard F<make> tool under compile-time. This is an
important fact, because the drawback of most enhanced Make derivates (like GNU
Make, BSD Make, etc.) is that one needs them under compile-time, i.e.  the
user has to install it on his system first. There is no such need when using
B<SMake> because the result of every B<SMake> run is a standard F<Makefile>
which usually can be interpreted by any F<make>. This does not mean you cannot
use features of your enhanced Make, it does only mean that B<SMake> features
are expanded to standard F<make> features.

SMake provides you with the following features:

=over 4

=item B<Include directive to integrate external files>

You can use include statements like the one found in BSD make(1) to tell
B<SMake> to integrate an external file at that position.   Say you have an
external file F<smk.bar>

  BAR
  BAZ

and a F<SMakefile> with the following contents:

  FOO
  .include <smk.bar>
  QUUX

Then the generated F<Makefile> reads:

  FOO
  BAR
  BAZ
  QUUX

Use C<.include ">I<file>C<"> to ignore the current include-path and read just
from the absolute path I<file>.

=item B<Option directive to overwrite command line options>

You can use the C<.opt> directive to set any options which will overwrite the
ones given on the command line.  For example, if you run

  $ smake SMakefile

per default the file F<Makefile> will be generated. If you always want the
output to be written to a file named F<Makefile.in> (for instance when using
the GNU autoconf package), you can add

  .opt -o Makefile.in

anywhere in F<SMakefile>.

=item B<Priority directive to set current processing priority>

Use the C<.pri> directive to increment, decrement or absolutely set the
processing priority which controls which I<define> and I<target> blocks are
used or removed in the output.  Enclose a block in pairs of decrement and
increment settings to let it be overwritable by higher priority ones.

An trivial example: When you have a F<SMakefile>

  .pri -10
  DEFINE = VALUE1
  target: source1 source2
    command1
    command2
  .pri +10
  
  DEFINE = VALUE2
  target: source3
    command3
    command4
      :

the generated F<Makefile> would result in

      :
  DEFINE = VALUE2
  target: source3
    command3
    command4
      :

You think this is silly? Yes, but only when used in such a simple form inside
a single file. It is B<SMake>'s primary feature and should be used as follows
in practice:

Say, you have the external files F<smk.stddef>

  .pri -1
  SRCS = 
  HDRS = 
  OBJS = 
  MISC = 
  
  TARGET = 
  
  DISTFILES = $(SRCS) $(HDRS) $(MISC)
  .pri +1

and F<smk.stdtarget>:

  .pri -1
  
  all: $(TARGET)
  
  clean:
    rm -f $(OBJS) $(TARGETS)
  
  dist:
    tar cvf dist.tar $(DISTFILES)
  
  .pri +1

Now a F<SMakefile> like 

  .include <smk.stddef>
  
  SRCS = testprog.y
  OBJS = testprog.c
  TARGET = testprog
   
  .include <smk.stdtarget>
   
  testprog.c: testprog.y
    yacc -v testprog.y
   
  testprog: testprog.c
    cc -o testprog testprog.c
   
  clean:
    rm -f $(OBJS) $(TARGET) *.output
  
will result in the following F<Makefile>:

  HDRS = 
  MISC = 

  DISTFILES = $(SRCS) $(HDRS) $(MISC)
  
  SRCS = testprog.y
  OBJS = testprog.c
  TARGET = testprog
  
  all: $(TARGET)
  
  dist:
    tar cvf dist.tar $(DISTFILES)
 
  testprog.c: testprog.y
    yacc -v testprog.y
 
  testprog: testprog.c
    cc -o testprog testprog.c
 
  clean:
    rm -f $(OBJS) $(TARGET) *.output

For more complex examples look at the files inside the distributions
F<include> subdir.

=back

These three directives gives you the power to create very short F<SMakefile>s
which will be automatically completed by B<SMake>. Write complex include files
which do all needed things and overwrite any locally different things (i.e.
defines and targets) inside the F<SMakefile>.

The program B<SMkMf> is similar to F<xmkmf> and just simplifies the task of
running F<smake> with appropriate include options over all F<SMakefile>s in a
subtree. Here the option B<-I> is adjusted for each subtree path. Use this as
the favorite frontend on the command line.

=head1 OPTIONS

=over 4

=item B<-I> I<directory>|I<pathlist>

Here the argument is either a plain I<directory> or a colon seperated
I<pathlist> of directories. B<SMake> looks for include files in these
directories.  The current working directory (``C<.>'') and the parent
directory (``C<..>'') are always part of the include-path.

There is a special variant of I<directory> arguments: those beginning with a
plus sign, i.e. ``C<+>I<directory>''.  This will cause B<SMake> to recursively
walk the parent directories of the current directory, looking for
subdirectories I<directory>. Each such subdirectory found during the search
will be appended to the include path, and treated as if it were included as a
full path argument to the B<-I> option. 

=item B<-o> I<outputfile>

Use I<outputfile> as the filename of the generated Makefile instead of
F<Makefile>.

=item B<-a>

Forces B<SMkMf> to operate on all F<SMakefile>s recursively found in the
current subtree.  [F<smkmf> only].

=item B<-q>

Forces quiet mode where no processing information is displayed.  [F<smkmf>
only].

=item B<-x>

Print debugging information in addition to normal processing. The debugging
information gives hints about the correct parsing of the input F<SMakefile>.
[F<smake> only]

=item B<-V>

Display the version identification string.

=item B<-h>

Display the usage summary.

=back

=head1 SEE ALSO

make(1)

=head1 HISTORY

The B<SMake> program was invented and initially implemented 1994 by Ralf S.
Engelschall for the privat project I<Push> (a never finished and released file
update tool) to get rid of the C<Makefile> chaos in the hierarchical I<Push>
source tree.

=head1 AUTHOR

 Ralf S. Engelschall
 rse@engelschall.com
 www.engelschall.com

=cut

##EOF##
