Provided by: dist_3.5-236-1_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)     Makefile target tests:

              •      ?target?:<text>: keeps <test> iff target is defined.
              •      %target%:<text>: keeps <test> iff target is not defined.

                     A makefile target is defined  as  a  standalone  target,  for  instance  the
                     depend.local target, which would be defined as:

                          depend.local:

                     Also  note that it is only valid for targets defined so far in the generated
                     makefile.  It is not a predicate that can be used to test for  targets  that
                     will eventually be defined later on in the generation.

       4)     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 that construct. :-)

              Indeed, 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 about logic? ;-)

              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 occurrences 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.

       5)     Initializations:

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

       6)     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)