Provided by: dist_3.5-30-3.3_all bug

NAME

       jmake - a generic makefile builder

SYNOPSIS

       jmake [ cpp options ]

DESCRIPTION

       Jmake  builds  a makefile out of a rather high level description held in a Jmakefile file.
       The generated file is a Makefile.SH rather than a simple makefile, which means it is ready
       to  be  used  in conjonction with metaconfig.  In particular, parameters such as "where to
       install executables" will be automatically determined by Configure  and  only  the  needed
       parameters will be taken into account.

       To use jmake you have to write a Jmakefile first, which describes the way things are to be
       built. Your Jmakefile will be included inside  a  generic  template  through  the  C  pre-
       processor.   This  means  you  may  use  the  usual  C  /**/ comments, but not the shell #
       comments.  The C comments will not appear in the generated Makefile.SH but lines  starting
       with  ;#  will finally appear as shell comments. If you have to write the string /* in the
       generated Makefile.SH then you have to escape it (otherwise jmake will think of it as  the
       start of a C comment). Simply put a # in front of the *, as in /#*.

       You  have  a  set of macros at your disposal, and all these macros are listed in the Index
       file, along with the piece of code they will expand to. Usually,  a  Jmakefile  is  fairly
       small  and  thus easier to maintain than a huge Makefile.  Some internal powerful commands
       allow you to write portable makefiles  easily,  without  having  to  spend  many  efforts,
       because someone else already did the job for you :-).

       When  you  want  to generate your makefile, you usually do not run jmake but use the jmkmf
       script which is a wrapper and will invoke jmake with the correct options.

       All the knowledge of jmake is held in two files: the template  Jmake.tmpl  and  the  macro
       definition  file  Jmake.rules.   The  first  file  includes  the  second,  along  with the
       Jmakefile.  It is sometimes necessary to know how things works to be able to correctly use
       all  the  features  provided.  For  instance,  you  may have to write your own rules for a
       specific project. Although you cannot overwrite the predefined rules, you can  extent  the
       Jmake.rules  file  or simply add your macros in your Jmakefile.  You may also use #include
       statements when you want to share these macros and do not want to duplicate the code.

       The syntax in Jmake.rules is not elegant at all, but:

       -      It is easy to parse (like sendmail.cf or troff files).
       -      The rules are not supposed to change very often.
       -      It is simple enough to be mastered in five minutes. :-)

              Here is a small description:

       1)     To deal with various cpp implementations:

              •      Final @!\ means: end of line, next line starts at the left margin.
              •      Final @@\ means: end of line, next line is to be indented by one tab.

              There should always be one of @!\ or @@\  at  the  end  of  each  line.   The  only
              exception  is  for  macros  that  are  to  be  used  as  part  of a rule body (e.g.
              RemoveTargetProgram). In that case, the first line (which holds the #define) should
              end with a single backslash.

       2)     Symbol definitions:

              •      >SYMBOL: defines the symbol.
              •      ?SYMBOL:<text>: keeps <text> iff SYMBOL is defined.
              •      %SYMBOL:<text>: keeps <text> iff SYMBOL is not defined.

              The ?SYM can be nested (logical AND), as in:

                   ?SYMBOL:%TOKEN:text

              which  will  keep  text  if  SYMBOL is defined and TOKEN undefined.  To implement a
              logical OR, see below.

       3)     Commands:

              Commands can be passed to jmake. They start with a leading '|'.  Available commands
              are:

              •      |suffix <sx>: adds <sx> to the .SUFFIXES: list in the makefile.

              •      |rule:<text>: adds <text> to the building rule section.

              •      |rule: <text>: same as before, with a leading tab.

              •      |skip: skips text until a line starting with '-skip' is found.

              •      |subst: begins section where lines will be subject to variable substitution,
                     until '-subst' is found.  This means that when the Makefile.SH is  run,  all
                     instances of $var within the subst section will be substituted by the shell.

              •      |shell:  emits  section  until  matching  '-shell'  as-is  in  the generated
                     Makefile.SH.  This can be useful to  prepare  |case  sections.   It  is  not
                     allowed to nest shell sections.

              •      |case:  this  command must be followed by a shell variable name (without its
                     leading '$' sign) and a case-style pattern, for instance the string "var  in
                     f*".   It  will generate the corresponding "case" test in the Makefile.SH on
                     the "$var" value and only if this test is true will the  section  until  the
                     matching  '-case'  be generated in the Makefile when Makefile.SH is run.  It
                     is possible to nest case sections freely.

              •      |expand <pattern>: expand lines until '-expand' with <pattern>.  A  complete
                     example is shown below.

              •      |once <symbol>: text up to '-once' appears only the first time.

              The  '|'  commands cannot be nested, unless otherwise noted.  In particular, due to
              the simple implementation of |skip, it is impossible to put |skip inside a  skipped
              part.  However,  a  |once  section  may have |skip sections.  It is allowed to nest
              |case sections at will.

              Here is a way to implement a logical OR:

                   /* Implements SYMBOL or not TOKEN */
                   ?SYMBOL:text        /* Keeps text if SYMBOL */
                   %SYMBOL:|skip
                        %TOKEN:text         /* Keeps text if not TOKEN */
                   -skip

              Actually, this is ugly, because the text has to appear twice.  Fortunately,  I  did
              not use it. :-)

              But  actually,  as  you  have  surely  already guessed, the best way to implement a
              logical OR is to use De Morgan's Law:

                   not (p or q) <=> not p and not q

                   /* Implements SYMBOL or not TOKEN (attempt #2) */
                   %SYMBOL:?TOKEN:|skip
                   text                     /* If SYMBOL or not TOKEN */
                   -skip

              Who said they didn't care ? ;-)

              Expansion is done with the expand command.  It has  been  provided  to  avoid  some
              cumbersome writings in makefiles when you have to repeat some silly lines that only
              differ in file names, for instance.  Let's look at an example first:

                   |expand a!foo bar! b!yes no!
                   !a::
                        echo !a, !b
                   -expand

              Then two rules will be printed, and the values of (a,b) for the first will be (foo,
              yes),  for  the  second (bar, no).  Substitution is controled by the '!' character.
              If the word to be substituted is part of another one, detach with the ^^  construct
              as  in:   !b^^c.   It is possible to use Makefile macros in the <pattern>, and they
              will be expanded by jmake.  If this is not what you want, escape the first '$' sign
              (this  is  a  Makefile  escape, i.e. you must double the '$', not precede it with a
              backslash). A // stands for the null substitution value.
              The ^^^ construct behaves like ^^, i.e. it is stripped out, but it also removes any
              following white space after the ^^^.  If you prepend something to a macro argument,
              and that macro argument was written with spaces before it, then this will  let  you
              concatenate something right before that argument's final value.

              Here  is  another  example  which  shows  how  the macro Expand can be used.  It is
              defined in Jmake.rules as:

                   #define Expand(rule, pattern) @!\
                   |expand pattern @!\
                   rule @!\
                   -expand

              So we can write in the Jmakefile:

                   |skip
                   A = foo bar
                   -skip

                   #define Rule @!\
                   $(DIR)/!a^^.o: !a^^.o @@\
                        $(CC) -c !a^^.c @@\
                        $(MV) !a^^.o $(DIR)

                   Expand(Rule, a!$(A)!)

              which will generate in Makefile.SH:

                   $(DIR)/foo.o: foo.o
                        $(CC) -c foo.c
                        $(MV) foo.o $(DIR)

                   $(DIR)/bar.o: bar.o
                        $(CC) -c bar.c
                        $(MV) bar.o $$(DIR)

              The 'A' declaration has been surrounded by skip, so that it does not appear in  the
              generated  Makefile.SH,  but  it  will  be  taken  into  account  by  jmake for the
              substitution in the pattern.

              The number of expansions is determined by the number of  possible  values  for  the
              first  parameter.  If other parameters have less substitution values, they will get
              void ones.

              It is possible to add a regular expression at the end of  '-expand'.  This  regular
              expression will be removed from the final set of expansion at the end of each line.
              It is also possible to do substitutions in the expanded item, by using  the  syntax
              (if  'f'  is  the  expanded  variable) !f:<p>=<q> where <p> and <q> are two regular
              expressions (without spaces).  The pattern <p> will be replaced by the pattern  <q>
              (only the first occurrence will be replaced).

              Finally, you may refer in the expanded section to variables whose value is computed
              via another expansion, which makes it easy to define generic Jmakefiles.

              Example:

                   SRC = foo.c bar.c
                   OBJ = \
                   |expand f!$(SRC)!
                        !f:\.c=\.o \
                   -expand \\
                   INC = \
                   |expand f!$(OBJ)!
                        !f:\.o=\.h \
                   -expand \\

              which will generate in Makefile.SH:

                   SRC = foo.c bar.c
                   OBJ = \
                        foo.o \
                        bar.o
                   INC = \
                        foo.h \
                        bar.h

              Do not forget to protect special characters in your  regular  expressions  such  as
              backslash, point, etc...

              The  once  command is tagged with a name. The first time the name appears, the once
              construct is ignored and the text up to '-once' will be  copied  in  the  generated
              Makefile.SH.   However,  future  occurences  of the same name will be ignored (once
              will behave like skip).

              Example:

                   |once this_is_a_name
                   <text>
                   -once

              The shell command can be used to generate a shell fragment in the Makefile.SH.  For
              instance, the following section in the Jmakefile:

                   |shell
                   case "$d_usegtk1" in
                   define) glib=1; gtk=1;;
                   esac
                   -shell

              will  cause  the  generation of the enclosed fragment in the Makefile.SH to compute
              the values of the glib and  gtk  variables  based  on  the  configuration  variable
              d_usegtk1 set by running Configure.

              In  turn,  this  can  be  used in subsequent case sections to activate parts of the
              Makefile only when building for GTK1 using glib-1.x:

                   |case glib in 1
                   display:
                        echo "Building for glib-1.x"
                   -case

              This section will generate something like this in the Makefile.SH:

                   !NO!SUBS!
                   case "$glib" in
                   1)
                        $spitshell >>Makefile <<'!NO!SUBS!'
                   display:
                        echo "Building for glib-1.x"
                   !NO!SUBS!
                        ;;
                   esac
                   $spitshell >>Makefile <<'!NO!SUBS!'

              And when running Makefile.SH, the  "display"  rule  above  will  only  appear  when
              building  for glib-1.x.  The form of the final Makefile can therefore depend on the
              configuration options chosen when Configure was run.

       4)     Initializations:

              •      +<line>: Puts the whole line in the initialization section.
              •      ++SYMBOL <value>: Adds <value> to the SYMBOL macro.

       5)     User-defined variables:

              The user may define CFLAGS, LDFLAGS or DPFLAGS as additional flags to be used in  C
              compilation,  linking phase or depend target. It is thus possible to add some extra
              flags such as -I or libraries for Makefiles in specific sub-directories.

AUTHOR

       Raphael Manfredi <Raphael_Manfredi@pobox.com>

FILES

       Jmakefile           High level description of Makefile.SH
       Jmake.rules         File holding the macro definitions
       Jmake.tmpl          Template used to mould Makefile.SH

BUGS

       On systems whose cpp reduces multiple tabs and spaces to a single space, jmake attempts to
       put  back  any necessary tabs (which make expects in front of rules) but does not properly
       formats the body of the rule itself.

       There is a bootstraping problem when creating the first Makefile.SH,  because  you  cannot
       run  it  through  a  shell  until  there  is  a decent Configure script, but you can't run
       metaconfig before there is a Makefile.SH or some needed symbols will not be defined.

SEE ALSO

       jmkmf(1), metaconfig(1).

                                               ram                                       JMAKE(1)