The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

SMake - Makefile generator

VERSION

@V@

SYNOPSIS

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

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

DESCRIPTION

SMake is a powerful mechanism to generate standard Makefiles out of skeleton Makefiles 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 (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 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 SMake is a Makefile generator, not an evaluator like make, i.e. it generates standard Makefiles at development which are later evaluated by the standard 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 SMake because the result of every SMake run is a standard Makefile which usually can be interpreted by any make. This does not mean you cannot use features of your enhanced Make, it does only mean that SMake features are expanded to standard make features.

SMake provides you with the following features:

Include directive to integrate external files

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

  BAR
  BAZ

and a SMakefile with the following contents:

  FOO
  .include <smk.bar>
  QUUX

Then the generated Makefile reads:

  FOO
  BAR
  BAZ
  QUUX

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

Option directive to overwrite command line options

You can use the .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 Makefile will be generated. If you always want the output to be written to a file named Makefile.in (for instance when using the GNU autoconf package), you can add

  .opt -o Makefile.in

anywhere in SMakefile.

Priority directive to set current processing priority

Use the .pri directive to increment, decrement or absolutely set the processing priority which controls which define and 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 SMakefile

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

the generated 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 SMake's primary feature and should be used as follows in practice:

Say, you have the external files smk.stddef

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

and smk.stdtarget:

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

Now a 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 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 include subdir.

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

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

OPTIONS

-I directory|pathlist

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

-o outputfile

Use outputfile as the filename of the generated Makefile instead of Makefile.

-a

Forces SMkMf to operate on all SMakefiles recursively found in the current subtree. [smkmf only].

-q

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

-x

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

-V

Display the version identification string.

-h

Display the usage summary.

AUTHOR

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

SEEALSO

make(1)