Man Linux: Main Page and Category List

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