[This Index is automatically generated from Jmake.rules file. Do not
edit this file or your changes will be lost. Edit Jmake.rules instead.]

This file contains a listing of all the macros that can be used in a
Jmakefile. Only a few of these should be used in the Jmakefile (they
are the top-level macros). However, some low-level ones may be useful,
but it is up to you to make that decision. This explains why this file
holds all the available macros for jmake.

In the following listing, the macros are separated by a line of dashes.
The signature of the macro is given, then a small comment of what it
does precedes the actual definition.

Lines preceded by '->' show the set of symbols defined when the macro is
used. Initialization lines are shown as-is, i.e. have the form SYM = val
while concatenation is shown by SYM += val (which means val is added to
the value of SYM).

Conditional lines are preceded by tests like (if SYM). This means the line
is to be kept if and only if the symbol SYM is defined. Other internal
requests are not formatted yet.

------------------------------------------------------------------------
AddSuffix(ext):
    Adds a sufix to the .SUFFIXES: list.

    .SUFFIXES: ext

------------------------------------------------------------------------
AddedByConfigure(files):
    Gives name of the files generated by Configure that can safely
    be removed when a "make clobber" is issued. Not that it is useless
    to name config.h or config.sh because these are already taken care
    of by jmake.

	-> RM.

    local_clobber::
        $(RM) files

------------------------------------------------------------------------
AliasedLibraryTarget(libname,alias):
    Generate rules to link one library to another.

	-> RM LN.

    AllTarget(lib/**/alias.a)

    lib/**/alias.a: lib^^libname.a
        $(RM) $@
        $(LN) lib/**/libname.a $@

------------------------------------------------------------------------
AllTarget(depends):
    Generate rules to build necessary things during make all.

	-> RM.

    all:: depends

    local_realclean::
        $(RM) depends

------------------------------------------------------------------------
BuildMakefile():
    Generate rules to build a Makefile from a Makefile.SH.

    Makefile: Makefile.SH
        /bin/sh Makefile.SH

------------------------------------------------------------------------
BuildMakefileSH(jmakeflags):
    Generate rules to build a Makefile.SH from an Jmakefile and any
    special jmake flags.  This is generally done automatically by the
    template or by any special Jmakefiles.
    This function will simply touch Makefile.SH if no $(TOP)/.package
    exists, assuming the Jmakefile is not in a production environment.

	-> RM MV.

    Makefile.SH: Jmakefile
        -@if test -f $(TOP)/.package; then \
            if test -f Makefile.SH; then \
                echo "    $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \
                $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \
            fi; \
            echo "    $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" jmakeflags; \
            $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) jmakeflags; \
        else touch $@; exit 0; fi

------------------------------------------------------------------------
CleanSubdirs():
    Generate rules to recursively clean out garbage files.

    NamedCleanTargetSubdirs(clean,"Cleaning",/**/)
    NamedCleanTargetSubdirs(realclean,"Real cleaning",/**/)
    NamedCleanTargetSubdirs(clobber,"Clobbering",/**/)

------------------------------------------------------------------------
CleanTarget():
    Generate rules to remove any garbage files.

	-> RM.

    (if SUBDIRS) clean: sub_clean local_clean
    (not SUBDIRS) clean: local_clean
    (if SUBDIRS) realclean: sub_realclean local_realclean
    (not SUBDIRS) realclean: local_realclean
    (if SUBDIRS) clobber: sub_clobber local_clobber
    (not SUBDIRS) clobber: local_clobber

    local_clean::
        $(RM) core *~ *.o

    local_realclean:: local_clean
    (if TOP)  $(RM) -r UU

    local_clobber:: local_realclean
    (not TOP)  $(RM) Makefile config.sh
    (if TOP)  $(RM) config.sh config.h
    (if TOP)  $(RM) -r .config
    (if TOP)  $(RM) Makefile

------------------------------------------------------------------------
CommonSubdirsRule(dirs):
    Rule for making $(TARGET) in every subdirectory, with $(VERB) as
    verbose message and $(FLAGS) as additional flags.

	-> MAKE.

    subdirs:
        @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
        for i in dirs ;\
        do \
            (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \
                $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \
        done

------------------------------------------------------------------------
ComplexProgramTarget(program):
    Generate rules for compiling and linking the program specified by
    $(OBJS) and $(SRCS), installing the program and its man page, and
    generating dependencies.  It should only be used in Jmakefiles
    that describe a single program.

	-> CC JLDFLAGS LIBS BINDIR MANSRC.

	OBJECTS += $(OBJS)
	SOURCES += $(SRCS)

    NormalObjectRule()
    AllTarget(program)

    program: $(OBJS)
        RemoveTargetProgram($@)
        $(CC) -o $@ $(OBJS) $(JLDFLAGS) $(LIBS)

    InstallProgram(program,$(BINDIR))
    InstallManPage(program,$(MANSRC))
    DependTarget()
    LintTarget()

------------------------------------------------------------------------
ComplexProgramTarget_1(program):
    Generate rules for compiling and linking the program specified by
    $(OBJS1) and $(SRCS1), installing the program and its man page,
    and generating dependencies for it and any programs described by
    $(SRCS2) and $(SRCS3).  It should be used to build the primary
    program in Jmakefiles that describe multiple programs.

	-> CC JLDFLAGS LIBS BINDIR MANSRC.

	OBJECTS += $(OBJS1)
	SOURCES += $(SRCS1)

    NormalObjectRule()
    AllTarget(program)

    program: $(OBJS1)
        RemoveTargetProgram($@)
        $(CC) -o $@ $(OBJS1) $(JLDFLAGS) $(LIBS)

    InstallProgram(program,$(BINDIR))
    InstallManPage(program,$(MANSRC))

    DependTarget()
    LintTarget()

------------------------------------------------------------------------
ComplexProgramTarget_2(program):
    Generate rules for compiling and linking the program specified by
    $(OBJS2) and $(SRCS2) and installing the program and man page.
    It should be used to build the second program in Jmakefiles
    describing more than one program.

	-> CC JLDFLAGS LIBS BINDIR MANSRC.

	OBJECTS += $(OBJS2)
	SOURCES += $(SRCS2)

    NormalObjectRule()
    AllTarget(program)

    program: $(OBJS2)
        RemoveTargetProgram($@)
        $(CC) -o $@ $(OBJS2) $(JLDFLAGS) $(LIBS)

    InstallProgram(program,$(BINDIR))
    InstallManPage(program,$(MANSRC))

------------------------------------------------------------------------
ComplexProgramTarget_3(program):
    Generate rules for compiling and linking the program specified by
    $(OBJS3) and $(SRCS3) and installing the program and man page.  It
    should be used to build the third program in Jmakefiles describing
    more than one program.

	-> CC JLDFLAGS LIBS BINDIR MANSRC.

	OBJECTS += $(OBJS3)
	SOURCES += $(SRCS3)

    NormalObjectRule()
    AllTarget(program)

    program: $(OBJS3)
        RemoveTargetProgram($@)
        $(CC) -o $@ $(OBJS3) $(JLDFLAGS) $(LIBS)

    InstallProgram(program,$(BINDIR))
    InstallManPage(program,$(MANSRC))

------------------------------------------------------------------------
ComplexShellManualTarget(manpages):
    Builds manual pages that are to be extracted from .SH files into
    .$manext files.

	-> INSTALL MANSRC RM.

	MANPAGE += manpages

    |once _ShellManualRule_
    .SH.$manext:
        /bin/sh $<

    -once
    AddSuffix(.SH)
    AddSuffix(.$manext)
    AllTarget(manpages)

    install.man::
        @if test "$(MANSRC)"; then \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            for file in manpages; do \
                (set -x; $(INSTALL) -c -m 444 $$file $(MANSRC)); \
            done; \
        else exit 0; fi

    deinstall.man::
        @if test "$(MANSRC)"; then \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            for file in manpages; do \
                (set -x; $(RM) $(MANSRC)/$$file); \
            done; \
        else exit 0; fi

------------------------------------------------------------------------
ComplexYaccInclude(base,prefix):
    Declare that program will need an include file produced by
    the output of yacc on base.y, which typically produces a file
    named y.tab.h, which will be renamed as base.h.
    The difference with SimpleYaccInclude is the identifying process
    of the y.tab.h file where all 'yy' are renamed to prefix.
    The only problem is that the dependencies towards base.h have
    to be manually given in the Jmakefile.

	-> RM SED CP.

    base.h: base.c
        @if test -f y.tab.h; then \
            echo "    $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h"; \
            $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h; \
            echo "    $(RM) y.tab.h"; \
            $(RM) y.tab.h; \
        elif test -f base.h; then \
            echo "    $(CP) base.h base.ht"; \
            $(CP) base.h base.ht; \
            echo "    $(SED) -e 's/yy\(.\)/prefix\1/g' < base.ht > base.h"; \
            $(SED) -e 's/yy\(.\)/prefix\1/g' < base.ht > base.h; \
            echo "    $(RM) base.ht"; \
            $(RM) base.ht; \
        else \
            exit 0; \
        fi

    local_realclean::
        $(RM) base.h

------------------------------------------------------------------------
ComplexYaccTarget(program,base,prefix):
    Declare a yacc base.y file to be used in the building of the
    specified target program. The source file must be given without
    its final .y extension. The name of the .c and .o will be
    derived from the source file basename provided.
    The difference with SimpleYaccTarget is the identifying process
    where all the 'yy' are replaced by the specified prefix.

	-> JYFLAGS YACC RM SED.

	SOURCES += base.y
	OBJECTS += base.o

    program: base.c

    base.c: base.y
        $(YACC) $(JYFLAGS) base.y
        $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.c > base.c
        $(SED) -e 's/yy\(.\)/prefix\1/g' < y.tab.h > base.h
        $(RM) y.tab.c y.tab.h

    local_realclean::
        $(RM) base.c

------------------------------------------------------------------------
CppScriptTarget(dst,src,defs,deplist):
    Generate rules to create a shell script by running the input
    through cpp.

	-> RM CPP.

    dst::  src deplist
        $(RM) $@
        $(CPP) defs <src | \
            sed -e '/^#  *[0-9][0-9]*  *.*$$/d' >$@
        chmod a+x $@

------------------------------------------------------------------------
DebuggedAndProfiledLibraryObjectRule():
    Generate make rules to build debuggable, profiled, and "normal"
    objects.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    .c.o:
        $(RM) $@ profiled/$@ debugger/$@
        $(CC) -pg -c $(JCFLAGS) $*.c
        $(MV) $*.o profiled/$*.o
        $(CC) -g -c $(JCFLAGS) $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(JCFLAGS) $*.c

    local_clean::
        -@if [ -d profiled ]; then echo "    $(RM) profiled/?*.o"; \
            $(RM) profiled/?*.o; else exit 0; fi
        -@if [ -d debugger ]; then echo "    $(RM) debugger/?*.o"; \
            $(RM) debugger/?*.o; else exit 0; fi

------------------------------------------------------------------------
DebuggedLibraryObjectRule():
    Generate make rules to build both debuggable and "normal"
    objects.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    .c.o:
        $(RM) $@ debugger/$@
        $(CC) -g -c $(JCFLAGS) $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(JCFLAGS) $*.c

    local_clean::
        -@if [ -d debugger ]; then echo "    $(RM) debugger/?*.o"; \
            $(RM) debugger/?*.o; else exit 0; fi

------------------------------------------------------------------------
DebuggedLibraryTarget(libname,srclist,objlist):
    Generate rules to create a debuggable library.

	-> RM AR RANLIB.

	SOURCES += srclist
	OBJECTS += objlist

    AllTarget(lib/**/libname^^_d.a)

    lib/**/libname^^_d.a: objlist
        $(RM) $@
        cd debugger; $(AR) ../$@ objlist
        $(RANLIB) $@

------------------------------------------------------------------------
DebuggedRelocatableTarget(objname,objlist):
    Generate rules to produce a debuggable relocatable object file
    instead of a library.

	-> RM LD.

    AllTarget(objname/**/_d.o)

    objname/**/_d.o: objlist
        $(RM) $@
        $(LD) -X -r objlist -o $@

------------------------------------------------------------------------
DependDependency():
    Generate rules to build the makedepend program.

    depend:: TOPDIR/mkdep

    TOPDIR/mkdep:
    (if TOP)  @echo "You have to run Configure first."; exit 1
    (not TOP)  @echo "You have to run Configure in $(TOP) first."; exit 1

------------------------------------------------------------------------
DependDirs(dirs):
    Generate rules to recursively compute dependencies as part of the
    make depend step.

    NamedTargetSubdirsRule(dirs,depend,"Depending",/**/)

------------------------------------------------------------------------
DependSubdirs():
    Generate rules to recursively compute dependencies as part of the
    make depend step.

    DependDirs($(SUBDIRS))

------------------------------------------------------------------------
DependTarget():
    Generate rules to compute dependencies for all files listed
    in $(SOURCES) (automatically generated macro).

	-> MKDEP SED RM.

	USRINC = $usrinc

    |once _DependTarget_
    DependDependency()

    depend::
        ($(SED) '/^# DO NOT DELETE/q' Makefile && \
        $(MKDEP) $(SOURCES) | \
        $(SED) -e 's:/usr/include[^ ]*::g; s:$(USRINC)[^ ]*::g; ' \
            -e '/: / b print' -e 'H; d; n; : print' -e 'x; s/\\\n//g' \
            -e 's/ /**/ */ /g; s/ :/:/;' -e '/: *$$/d' \
        ) > Makefile.new
        cp Makefile Makefile.bak
        cp Makefile.new Makefile
        $(RM) Makefile.new

    -once

------------------------------------------------------------------------
Expand(rule, pattern):
    This powerful macro expands the `rule' given a `pattern'. It
    relies on a built-in command in jmake. The expansion is
    documented in the short notes file that comes with jmake and
    gives some insights on the internal syntax.

    |expand pattern
    rule
    -expand

------------------------------------------------------------------------
ForceTarget():
    The force target will force reconstruction of all the other
    targets which include .FORCE in their own dependencies.

    |once _force_
    .FORCE:

    -once

------------------------------------------------------------------------
IdentifiedLexDependTarget(program,base,parser,prefix):
    Declare that program will need an include file produced by
    the output of lex on base.l, which typically produces a file
    named lex.yy.c which will be renamed as base.c. Besides, the
    lexical analyzer needs the file parser.h produced by running
    parser.y through yacc and renaming y.tab.h as parser.h.
    The lexical analyzer is identified with the supplied prefix,
    which replaces the regular 'yy' prefix in the symbol names.

    base.o: parser.h

    IdentifiedLexTarget(program,base,prefix)

------------------------------------------------------------------------
IdentifiedLexTarget(program,base,prefix):
    This declares a lex base.l file which is to be ran through
    lex to produce a base.c file. The prefix is used to replace
    the 'yy', so that the lexical analyzer may be identified.

	-> JLFLAGS LEX RM SED.

	SOURCES += base.l
	OBJECTS += base.o

    program: base.c

    base.c: base.l
        $(LEX) $(JLFLAGS) base.l
        $(SED) -e 's/yy\(.\)/prefix\1/g' < lex.yy.c > base.c
        $(RM) lex.yy.c

    local_realclean::
        $(RM) base.c

------------------------------------------------------------------------
IdentifiedParserTarget(program,lexic,parser,prefix):
    Specify that program is using the lex/yacc combination to
    produce a parser. The lexic and parser parameters are the
    base name of the .l and .y file, respectively. The parser
    produced is identified via its prefix, which replaces all
    the normally supplied 'yy' prefix, hence making it possible
    to have multiple parsers in a single executable.

    IdentifiedLexDependTarget(program,lexic,parser,prefix)
    IdentifiedYaccTarget(program,parser,prefix)

------------------------------------------------------------------------
IdentifiedYaccTarget(program,base,prefix):
    Declare a yacc base.y file which should produce a base.c and
    base.h file as derived from the output of yacc, to be used by
    the specified program. The specified prefix is used to remplace
    all the 'yy' in the generated file, for use when more than a
    single parser is needed in one executable.

    ComplexYaccTarget(program,base,prefix)
    ComplexYaccInclude(base,prefix)

------------------------------------------------------------------------
IncludesSubdirs():
    Generate rules to recursively put include files in build

    NamedTargetSubdirs(includes,including,/**/)

------------------------------------------------------------------------
Initialize(symbol,value):
    Puts the line symbol = value in the initialization section of
    Makefile.SH (the one that is subject to parameter substitutions).

	symbol = value

------------------------------------------------------------------------
InstallLibrary(libname,dest):
    Generate rules to install the indicated library.

	-> RANLIB INSTALL RM.

    install:: lib/**/libname.a
        $(INSTALL) -c -m 644 lib/**/libname.a dest
        $(RANLIB) dest/lib/**/libname.a
        chmod 444 dest/lib/**/libnane.a

    deinstall::
        $(RM) dest/lib/**/libname.a

------------------------------------------------------------------------
InstallLibraryAlias(libname,alias,dest):
    Generate rules to create a link from one library name to another
    for the purposes of aliasing.

	-> LN RM.

    install:: lib/**/libname.a
        $(RM) lib/**/alias.a
        -(cd dest; $(LN) lib/**/libname.a lib^^alias.a)

    deinstall::
        $(RM) dest/lib/**/alias.a

------------------------------------------------------------------------
InstallLintLibrary(libname,dest):
    Generate rules to install the indicated lint library.

	-> INSTALL RM.

    install.ln:: llib-l/**/libname.ln
        $(INSTALL) -c -m 444 llib-l/**/libname.ln dest

    deinstall.ln::
        $(RM) dest/llib-l/**/libname.ln

------------------------------------------------------------------------
InstallManPage(file,dest):
    Generate rules to install the indicated manual page.

    InstallManPageLong(file,dest,file)

------------------------------------------------------------------------
InstallManPageLong(file,destdir,dest):
    Generate rules to install the indicated manual page, giving it an
    alternate name.  This is used for installing man pages whose base
    name without the .man suffix would normally be longer than 8
    characters (the limit for using source code control systems on
    files systems with short file names).

	-> L INSTALL RM.

    install.man:: file.man
        $(INSTALL) -c -m 444 file.man destdir/dest.$(L)

    deinstall.man::
        $(RM) destdir/dest.$(L)

------------------------------------------------------------------------
InstallManScripts():
    Generate rule to install/deinstall manual pages for scripts listed
    in the automatically generated $(SCRIPTS) macro.

	-> RM INSTALL MANSRC L.

    |once _InstallManScripts_
    #ifndef NOMAN
    install.man::
        @if test "$(MANSRC)"; then \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            for file in $(SCRIPTS); do \
                if test -f $$file.man; then \
                    (set -x; \
                    $(INSTALL) -c -m 444 $$file.man $(MANSRC)/$$file.$(L)); \
                fi; \
            done; \
        else exit 0; fi

    deinstall.man::
        @if test "$(MANSRC)"; then \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            for file in $(SCRIPTS); do \
                (set -x; $(RM) $(MANSRC)/$$file.$(L)); \
            done; \
        else exit 0; fi

    #endif
    -once

------------------------------------------------------------------------
InstallManSubdirs():
    Generate rules to recursively install and deinstall manual pages.

    NamedTargetSubdirs(install.man,"Installing man pages",/**/)
    NamedTargetSubdirs(deinstall.man,"Deinstalling man pages",/**/)

------------------------------------------------------------------------
InstallMultiple(list,dest):
    Generate rules to install multiple files at once during the install
    step of the build using any install flags set in $(INSTALLFLAGS).

    InstallMultipleDest(install,list,dest)

------------------------------------------------------------------------
InstallMultipleDest(step,list,dest):
    Generate rules to install multiple files at once during a particular
    step in the build using any install flags set in $(INSTALLFLAGS).

    InstallMultipleDestFlags(step,list,dest,$(INSTALLFLAGS))

------------------------------------------------------------------------
InstallMultipleDestFlags(step,list,dest,flags):
    Generate rules to install multiple files at once during a particular
    step in the build using a specific set of install flags. The `step'
    must begin with "install".

	-> INSTALL RM.

    step:: list
        @case '${MFLAGS}' in *[i]*) set +e;; esac; \
        for i in list; do \
            (set -x; $(INSTALL) -c flags $$i dest); \
        done

    de/**/step::
        @case '${MFLAGS}' in *[i]*) set +e;; esac; \
        for i in list; do \
            (set -x; $(RM) dest/$$i); \
        done

------------------------------------------------------------------------
InstallMultipleFlags(list,dest,flags):
    Generate rules to install multiple files at once during the
    install step of the build using the given install flags.

    InstallMultipleDestFlags(install,list,dest,flags)

------------------------------------------------------------------------
InstallMultipleMan(list,dest):
    Generate rules to install a variety of manual pages
    during the install.man step of the build.

	-> L.

    InstallMultipleDest(install.$(L),list,dest)

------------------------------------------------------------------------
InstallNonExec(file,dest):
    Generate rules to install a data file using any special
    install flags.

	-> INSTALL RM.

    install:: file
        $(INSTALL) -c -m 444 file dest

    deinstall::
        $(RM) dest/file

------------------------------------------------------------------------
InstallProgram(program,dest):
    Generate rules to install an executable program using any special
    install flags set in $(INSTALLFLAGS).

    InstallProgramWithFlags(program,dest,/**/)

------------------------------------------------------------------------
InstallProgramWithFlags(program,dest,flags):
    Generate rules to install an executable program using given
    install flags.

	-> INSTALL RM.

    install:: program
        $(INSTALL) -c -s -m 555 flags program dest

    deinstall::
        $(RM) dest/program

------------------------------------------------------------------------
InstallScript(script,dest):
    Generate rules to install an executable script using any special
    install flags set in $(INSTALLFLAGS).

    InstallScriptWithFlags(script,dest,/**/)

------------------------------------------------------------------------
InstallScriptWithFlags(script,dest,flags):
    Generate rules to install an executable script using given
    install flags.

	-> INSTALL RM.

    install:: script
        $(INSTALL) -c -m 555 flags script dest

    deinstall::
        $(RM) dest/script

------------------------------------------------------------------------
InstallScripts():
    Generate rules to install all the scripts listed in the generated
    $(SCRIPTS) and $(LSCRIPTS) macros.

	-> SCRIPTDIR INSTALL RM.

    |once _InstallScripts_
    install:: $(SCRIPTS) $(LSCRIPTS)
        @for file in $(SCRIPTS) $(LSCRIPTS); do \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            (set -x; $(INSTALL) -c -m 555 $$file $(SCRIPTDIR)); \
        done

    deinstall::
        @for file in $(SCRIPTS) $(LSCRIPTS); do \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            (set -x; $(RM) $(SCRIPTDIR)/$$file); \
        done
    -once

------------------------------------------------------------------------
InstallSharedLibrary(libname,rev,dest):
    Generate rules to install the shared library.

	-> INSTALL RM.

    install:: lib/**/libname.so.rev
        $(INSTALL) -c -m 444 lib/**/libname.so.rev dest

    deinstall::
        $(RM) dest/lib/**/libname.so.rev

------------------------------------------------------------------------
InstallSharedLibraryData(libname,rev,dest):
    Generate rules to install the shared library data

	-> INSTALL RM.

    install:: lib/**/libname.sa.rev
        $(INSTALL) -c -m 444 lib/**/libname.sa.rev dest

    deinstall::
        $(RM) dest/lib/**/libname.sa.rev

------------------------------------------------------------------------
InstallSubdirs():
    Generate rules to recursively install and deinstall programs and
    files.

    NamedTargetSubdirs(install,"Installing",/**/)
    NamedTargetSubdirs(deinstall,"Deinstalling",/**/)

------------------------------------------------------------------------
LinkFileList(step,list,dir,sub):
    Link a list of list of files from one place to another

	-> LN.

    step:: list
        @case '${MFLAGS}' in *[i]*) set +e;; esac; \
        echo "    cd" dir; cd dir; for i in list; do (set -x; $(LN) sub/$$i .); done

------------------------------------------------------------------------
LinkSourceFile(src,dir):
    Snag source file from some other directory

	-> RM LN.

    src:  dir/src
        $(RM) $@
        $(LN) $? $@

------------------------------------------------------------------------
LintDirs(dirs):
    Generate rules to recursively lint directories as part of the
    make lint step.

    MakeLintSubdirs(dirs,lint)

------------------------------------------------------------------------
LintLibraryTarget(libname,srclist):
    Generate rules to create a lint library.  Note that the lint
    library is always forced to be newer than the library itself.

	-> RM LINT.

    lintlib:: llib-l/**/libname.ln

    llib-l/**/libname.ln: srclist
        $(RM) $@
        $(LINT) $(LINTLIBFLAG)/**/libname $(LINTFLAGS) srclist

------------------------------------------------------------------------
LintSubdirs():
    Generate rules to recursively lint directories as part of the
    make lint step.

    LintDirs($(SUBDIRS))

------------------------------------------------------------------------
LintTarget():
    Generate rules to lint $(SOURCES) (automatically generated)

    |once _LintTarget_
    NormalLintTarget($(SOURCES))
    -once

------------------------------------------------------------------------
MakeDirectories(step,dirs):
    Generate rules to create a hierarchy of directories.

    step::
        MakeDirs(dirs)

------------------------------------------------------------------------
MakeDirs(dirs):
    Creates a set of directories, even if some directories in the path
    do not already exist.There should be no '@!' at the end of the
    '#define' line, because this macro is used *inside* building rules.

	-> INSTALLDIR.

        @for dir in dirs; do \
            case '${MFLAGS}' in *[i]*) set +e;; esac; \
            (set -x; test -d $$dir || $(INSTALLDIR) $$dir); \
        done

------------------------------------------------------------------------
MakeInstallDirectories(dirs):
    Generate a rule to create a set of directories at installation
    time (removed by deinstall).

	-> RM.

    install::
        MakeDirs(dirs)

    deinstall::
        $(RM) -r dirs

------------------------------------------------------------------------
MakeLintLibSubdirs(dirs):
    Generate rules to recursively create lint libraries.

    MakeLintSubdirs(dirs,lintlib)

------------------------------------------------------------------------
MakeLintSubdirs(dirs,target):
    Generate rules to recursively lint directories as part of the
    named step.

    NamedTargetSubdirsRule(dirs,target,"Linting",/**/)

------------------------------------------------------------------------
MakeMakeSubdirs(target):
    Generate rules to recursively recreate target as part of the
    specified step in the build.  This assumes Makefile.SH has
    already been built (which is the case for a delivery), but does
    not rely on the existence of a Makefile.

	-> MAKE.

    target::
        @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
        for i in $(SUBDIRS);\
        do \
            echo "Making "target" in $(DIR)$$i..."; \
            (cd $$i || exit 1; \
            if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \
            $(MAKE) $(MFLAGS) target) \
        done

------------------------------------------------------------------------
MakeMakefilesSH():
    Generate rules to recursively recreate target as part of the
    specified step in the build.  If $(TOP) is set to an absolute
    path, don't prepend the ../ prefix.  This makes running things
    outside of the source tree to be much easier.

	-> MAKE.

    Makefiles.SH:: Makefile.SH
        @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
        for i in $(SUBDIRS);\
        do \
            case "$(DIR)$$i/" in \
            /**/*^^/^^*^^/^^*^^/^^*^^/) newtop=../../../..;; \
            /**/*^^/^^*^^/^^*^^/) newtop=../../..;; \
            /**/*^^/^^*^^/) newtop=../..;; \
            */**//) newtop=..;; \
            esac; \
            case "$(TOP)" in \
            //**/*) newtop="$(TOP)" ;; \
            esac; \
            echo "Making Makefiles.SH in $(DIR)$$i..."; \
            (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \
            Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\
            $(MAKE) $(MFLAGS) Makefiles.SH) \
        done

------------------------------------------------------------------------
MakeScriptFromCpp(name,defs):
    Generate rules to create a script from a file with a
    .cpp suffix.

    CppScriptTarget(name,name.cpp,defs,/**/)

------------------------------------------------------------------------
MakeSubdirs():
    Generate rules to do makes in the given subdirectories.

    NamedTargetSubdirs(all,"Making all",/**/)

------------------------------------------------------------------------
MakeSubincludesForBuild(step,dir,srclist):
    Make includes in sub directories.

	-> RM LN.

    step::  dir srclist
        @-(list=`echo srclist | sed -e 's/[^ ]*\///g'`; \
            set -x; cd dir; $(RM) $$list)
        @for i in srclist; do \
            (set -x; cd dir; $(LN) ../$$i .); \
        done

    MakeDirectories(dir,dir)

    local_realclean::
        @-(if [ -d dir ]; then \
            list=`echo srclist | sed -e 's/[^ ]*\///g'`; \
            set -x; cd dir; $(RM) $$list; else exit 0; fi)

------------------------------------------------------------------------
MakefileSubdirs():
    Generate rules to create Makefiles.

    MakeMakeSubdirs(Makefiles)
    MakeMakefilesSH()

------------------------------------------------------------------------
MakefileTarget():
    Generate rules to build a normal Makefile.

    BuildMakefileSH(/**/)
    BuildMakefile()

------------------------------------------------------------------------
NamedCleanTargetSubdirs(name,verb,flags):
    Recursively make a series of cleaning. We first clean the
    subdirectories, in case the Makefile is removed by the
    clean entry.

	-> MAKE.

    sub_/**/name::
        @$(MAKE) subdirs TARGET=name VERB=verb FLAGS=flags
        @echo "Back to $(CURRENT) for "name/**/...

------------------------------------------------------------------------
NamedTargetSubdirs(name,verb,flags):
    Recursively make a series of steps.

	-> MAKE.

    name::
        @$(MAKE) subdirs TARGET=name VERB=verb FLAGS=flags

------------------------------------------------------------------------
NamedTargetSubdirsRule(dirs,name,verb,flags):
    Recursively make a series of steps in the specified directories.

	-> MAKE.

    name::
        @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
        for i in dirs ;\
        do \
            (cd $$i ; echo verb "in $(DIR)$$i..."; \
                $(MAKE) $(MFLAGS) flags name); \
        done

------------------------------------------------------------------------
NoManPages():
    Actually forces the definition of NOMAN, which tells the jmake
    program to not generate rules for installing manual pages.

	-> NOMAN.

------------------------------------------------------------------------
NormalLexDependTarget(program,base,parser):
    Declare that program will need an include file produced by
    the output of lex on base.l, which typically produces a file
    named lex.yy.c which will be renamed as base.c. Besides, the
    lexical analyzer needs the file parser.h produced by running
    parser.y through yacc and renaming y.tab.h as parser.h.

    base.o: parser.h

    SimpleLexTarget(program,base)

------------------------------------------------------------------------
NormalLibraryObjectRule():
    Generate make rules to build "normal" objects.

	-> CC JCFLAGS RM.

    |once _ObjectRule_
    .c.o:
        $(RM) $@
        $(CC) -c $(JCFLAGS) $<

    -once

------------------------------------------------------------------------
NormalLibraryTarget(libname,srclist,objlist):
    Generate rules to create a library. The 'srclist' and 'objlist'
    parameters are added to SOURCES and OBJECTS macros. The 'srclist'
    is not otherwise used by this rule, but is necessary for make depend.

	-> RM AR RANLIB.

	OBJECTS += objlist
	SOURCES += srclist

    NormalLibraryObjectRule()
    AllTarget(lib/**/libname.a)

    lib/**/libname.a: objlist
        $(RM) $@
        $(AR) $@ objlist
        $(RANLIB) $@

------------------------------------------------------------------------
NormalLibraryTarget2(libname,srclist,objlist1,objlist2):
    Generate rules to create a library in two steps.  This is used to
    create libraries with large numbers of files.

	-> RM AR RANLIB.

	SOURCES += srclist
	OBJECTS += objlist1
	OBJECTS += objlist2

    NormalLibraryObjectRule()
    AllTarget(lib/**/libname.a)

    lib/**/libname.a: objlist1 objlist2
        $(RM) $@
        $(AR) $@ objlist1
        $(AR) $@ objlist2
        $(RANLIB) $@

------------------------------------------------------------------------
NormalLintTarget(srclist):
    Generate rules to lint a set of sources.

	-> LINT.

    lint:
        $(LINT) $(LINTFLAGS) srclist $(LINTLIBS)

------------------------------------------------------------------------
NormalObjectRule():
    Generate make rule to build usual object files.

	-> CC JCFLAGS.

    |once _ObjectRule_
    .c.o:
        $(CC) -c $(JCFLAGS) $<

    -once

------------------------------------------------------------------------
NormalParserTarget(program,lexic,parser):
    Specify that program is using the lex/yacc combination to
    produce a parser. The lexic and parser parameters are the
    base name of the .l and .y file, respectively.

    NormalLexDependTarget(program,lexic,parser)
    NormalYaccTarget(program,parser)

------------------------------------------------------------------------
NormalProgramTarget(program,sources,objects):
    Generate rules to compile and link the indicated program; since
    it does not use any default object files, it may be used for
    multiple programs in the same Jmakefile.

	-> CC RM JLDFLAGS LIBS.

	OBJECTS += objects
	SOURCES += sources

    NormalObjectRule()
    AllTarget(program)

    program: objects
        RemoveTargetProgram($@)
        $(CC) -o $@ objects $(JLDFLAGS) $(LIBS)

------------------------------------------------------------------------
NormalRelocatableTarget(objname,objlist):
    Generate rules to produce a relocatable object file instead of a
    library.

	-> RM LD JLKFLAGS.

    AllTarget(objname.o)

    objname.o: objlist
        $(RM) $@
        $(LD) $(JLKFLAGS) -r objlist -o $@

------------------------------------------------------------------------
NormalSharedLibraryDataTarget(libname,rev,salist):
    Generate rules to create shlib data file; build it into a
    different name so that the we don't hose people by having the
    library gone for long periods.

	-> RM AR RANLIB.

    AllTarget(lib/**/libname.sa.rev)

    lib/**/libname.sa.rev:  salist
        $(RM) $@
        $(AR) $@ salist
        $(RANLIB) $@

------------------------------------------------------------------------
NormalSharedLibraryTarget(libname,rev,solist):
    Generate rules to create a shared library; build it into a
    different name so that the we don't hose people by having the
    library gone for long periods.

	-> RM LD MV.

    AllTarget(lib/**/libname.so.rev)

    lib/**/libname.so.rev:  solist
        $(RM) $@~
        (cd shared; $(LD) -o ../$@~ -assert pure-text solist)
        $(RM) $@
        $(MV) $@~ $@

------------------------------------------------------------------------
NormalYaccTarget(program,base):
    Declare a yacc base.y file which should produce a base.c and
    base.h file as derived from the output of yacc, to be used by
    the specified program.

    SimpleYaccTarget(program,base)
    SimpleYaccInclude(base)

------------------------------------------------------------------------
PrelinkedRelocatableTarget(objname,objlist,libs):
    Generate rules to produce a relocatable object file instead of a
    library.

	-> RM LD JLKFLAGS.

    AllTarget(objname.o)

    objname.o: objlist
        $(RM) $@
        $(LD) $(JLKFLAGS) -r objlist -o $@ libs

------------------------------------------------------------------------
ProfiledLibraryObjectRule():
    Generate make rules to build both profiled and "normal" objects.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi

    .c.o:
        $(RM) $@ profiled/$@
        $(CC) -pg -c $(JCFLAGS) $*.c
        $(MV) $*.o profiled/$*.o
        $(CC) -c $(JCFLAGS) $*.c

    local_clean::
        -@if [ -d profiled ]; then echo "    $(RM) profiled/?*.o"; \
            $(RM) profiled/?*.o; else exit 0; fi

------------------------------------------------------------------------
ProfiledLibraryTarget(libname,srclist,objlist):
    Generate rules to create a profiled library.

	-> RM AR RANLIB.

	SOURCES += srclist
	OBJECTS += objlist

    AllTarget(lib/**/libname^^_p.a)

    lib/**/libname^^_p.a: objlist
        $(RM) $@
        cd profiled; $(AR) ../$@ objlist
        $(RANLIB) $@

------------------------------------------------------------------------
ProfiledRelocatableTarget(objname,objlist):
    Generate rules to produce a profiled relocatable object file
    instead of a library.

	-> RM LD.

    AllTarget(objname/**/_p.o)

    objname/**/_p.o: objlist
        $(RM) $@
        $(LD) -X -r objlist -o $@

------------------------------------------------------------------------
RemoteDependency(directory,dependency):
    Specify rules for making a remote dependency.

	-> MAKE.

    ForceTarget()
    |once =directory/dependency=
    directory/dependency: .FORCE
        @echo "Checking "dependency" in "directory"..."
        cd directory; $(MAKE) dependency
        @echo "Continuing in $(CURRENT)..."

    -once

------------------------------------------------------------------------
RemoteTargetDependency(target,directory,dependency):
    A local target may rely on a remote dependency (e.g. a library)
    made in a separate directory. This rule explicits the dependency
    and forces a make of that dependency in the remote directory.

	-> MAKE.

    RemoteDependency(directory,dependency)
    target: directory/dependency

------------------------------------------------------------------------
RemoveTargetProgram(program):
    This is used in some other macros in order to remove the target
    before starting its building (saves disk space).  There should be
    no '@!' at the end of the '#define' line, because this macro is
    used *inside* building rules.

	-> RM MV.

        $(RM) program
        if test -f program; then $(MV) program program/**/~; else exit 0; fi

------------------------------------------------------------------------
SetSubdirs(subdirs):
    Actually forces the definition of SUBDIRS, and lets the user
    specify what the sub-directories are.  This will be added to the
    customization part.

	-> SUBDIRS.

	SUBDIRS = subdirs

------------------------------------------------------------------------
SharedAndDebuggedLibraryObjectRule():
    Generate make rules to build shared, debuggable, and "normal"
    object files.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d shared ]; then mkdir shared; else exit 0; fi
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    .c.o:
        $(RM) $@ shared/$@ debugger/$@
        $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) $*.c
        $(MV) $*.o shared/$*.o
        $(CC) -g -c $(SHLIBDEF) $(JCFLAGS) $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(SHLIBDEF) $(JCFLAGS) $*.c

    local_clean::
        -@if [ -d shared ]; then echo "    $(RM) shared/?*.o"; \
            $(RM) shared/?*.o; else exit 0; fi
        -@if [ -d debugger ]; then echo "    $(RM) debugger/?*.o"; \
            $(RM) debugger/?*.o; else exit 0; fi

------------------------------------------------------------------------
SharedLibraryObjectRule():
    Generate make rules to build shared and "normal" object files.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d shared ]; then mkdir shared; else exit 0; fi

    .c.o:
        $(RM) $@ shared/$@
        $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) $*.c
        $(MV) $*.o shared/$*.o
        $(CC) -c $(SHLIBDEF) $(JCFLAGS) $*.c

    local_clean::
        -@if [ -d shared ]; then echo "    $(RM) shared/?*.o"; \
            $(RM) shared/?*.o; else exit 0; fi

------------------------------------------------------------------------
ShellScriptLongTarget(basename,scriptname):
    Generate rules to create a set of scripts from .SH files where
    the name of the generated file is different from the basename of
    the .SH file (when, for instance, the total length with the .SH
    extension would not leave enough space for RCS ,v extension).

	-> RM MANSRC.

	LSCRIPTS += scriptname

    AllTarget(scriptname)

    scriptname: basename/**/.SH
        /bin/sh basename/**/.SH

    InstallScripts()
    #ifndef NOMAN
    InstallManPageLong(basename,$(MANSRC),scriptname)
    #endif

------------------------------------------------------------------------
ShellScriptTarget(scripts):
    Generate rules to create and install a set of scripts from
    .SH files. Man pages derived from the name of the scripts are
    also installed unless NoManPages() is specified.

    ShellScriptTargetExt(scripts,.SH)

------------------------------------------------------------------------
ShellScriptTargetExt(scripts,ext):
    Generate rules to create and install a set of scripts from
    ext files (.sh and .SH are the most common examples). Man pages
    derived from the name of the scripts are also installed unless
    NoManPages() is specified.

	SCRIPTS += scripts

    SimpleShellScriptTargetExt(scripts,ext)
    InstallScripts()
    InstallManScripts()

------------------------------------------------------------------------
SimpleLexTarget(program,base):
    This declares a lex base.l file which is to be ran through
    lex to produce a base.c file.

	-> JLFLAGS LEX RM MV.

	SOURCES += base.l
	OBJECTS += base.o

    |once _LexRule_
    .l.c:
        $(LEX) $(JLFLAGS) $<
        $(MV) lex.yy.c $@

    -once
    AddSuffix(.l)
    program: base.c

    local_realclean::
        $(RM) base.c

------------------------------------------------------------------------
SimpleProgramTarget(program):
    Generate rules for compiling and linking programs that only have
    one C source file.  It should only be used in Jmakefiles that
    describe a single program.

    NormalProgramTarget(program,program.c,program.o)

------------------------------------------------------------------------
SimpleShellScriptTarget(scripts):
    Generate rules to create a set of scripts from .SH files.

    SimpleShellScriptTargetExt(scripts,.SH)

------------------------------------------------------------------------
SimpleShellScriptTargetExt(scripts,ext):
    Generate rules to create a set of scripts from ext files where
    ext is usually something like .sh or .SH, or whatever file
    extension you like..

	-> RM.

    AllTarget(scripts)

    |expand s!scripts!
    !s: !s/**/ext
        /bin/sh !s/**/ext

    -expand

------------------------------------------------------------------------
SimpleYaccInclude(base):
    Declare that program will need an include file produced by
    the output of yacc on base.y, which typically produces a file
    named y.tab.h, which will be renamed as base.h.
    The only problem is that the dependencies towards base.h have
    to be manually given in the Jmakefile.

	-> MV RM.

    base.h: base.c
        @if test -f y.tab.h; then \
            echo "    $(MV) y.tab.h $@"; \
            $(MV) y.tab.h $@; \
        else \
            exit 0; \
        fi

    local_realclean::
        $(RM) base.h

------------------------------------------------------------------------
SimpleYaccTarget(program,base):
    Declare a yacc base.y file to be used in the building of the
    specified target program. The source file must be given without
    its final .y extension. The name of the .c and .o will be
    derived from the source file basename provided.

	-> JYFLAGS YACC RM MV.

	SOURCES += base.y
	OBJECTS += base.o

    YaccRule()
    program: base.c

    local_realclean::
        $(RM) base.c

------------------------------------------------------------------------
SingleProgramTarget(program,objects,libs):
    Obsolete version of NormalProgramTarget that doesn't have
    deplibs.

    NormalProgramTarget(program,objects,libs)

------------------------------------------------------------------------
SpecialDebuggedAndProfiledObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags and to make
    debuggable and profiled versions.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    objs:    depends
        $(RM) $@ profiled/$@ debugger/$@
        $(CC) -pg -c $(JCFLAGS) options $*.c
        $(MV) $*.o profiled/$*.o
        $(CC) -g -c $(JCFLAGS) options $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(JCFLAGS) options $*.c

------------------------------------------------------------------------
SpecialDebuggedObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags and to make a
    debuggable version.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    objs:    depends
        $(RM) $@ debugger/$@
        $(CC) -g -c $(JCFLAGS) options $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(JCFLAGS) options $*.c

------------------------------------------------------------------------
SpecialObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags.

	-> RM CC JCFLAGS.

    objs:    depends
        $(RM) $@
        $(CC) -c $(JCFLAGS) options $*.c

------------------------------------------------------------------------
SpecialProfiledObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags and to make a
    profiled version.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d profiled ]; then mkdir profiled; else exit 0; fi

    objs:    depends
        $(RM) $@ profiled/$@
        $(CC) -pg -c $(JCFLAGS) options $*.c
        $(MV) $*.o profiled/$*.o
        $(CC) -c $(JCFLAGS) options $*.c

------------------------------------------------------------------------
SpecialSharedAndDebuggedObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags and to make
    shared and debuggable versions.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d shared ]; then mkdir shared; else exit 0; fi
        @if [ ! -d debugger ]; then mkdir debugger; else exit 0; fi

    objs:    depends
        $(RM) $@ shared/$@ debugger/$@
        $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) options $*.c
        $(MV) $*.o shared/$*.o
        $(CC) -g -c $(SHLIBDEF) $(JCFLAGS) options $*.c
        $(MV) $*.o debugger/$*.o
        $(CC) -c $(SHLIBDEF) $(JCFLAGS) options $*.c

------------------------------------------------------------------------
SpecialSharedObjectRule(objs,depends,options):
    Generate rules to compile a file with special flags and to make
    shared and debuggable versions.

	-> RM CC MV JCFLAGS.

    all::
        @if [ ! -d shared ]; then mkdir shared; else exit 0; fi

    objs:    depends
        $(RM) $@ shared/$@
        $(CC) -pic -c $(SHAREDCODEDEF) $(SHLIBDEF) $(JCFLAGS) options $*.c
        $(MV) $*.o shared/$*.o
        $(CC) -c $(SHLIBDEF) $(JCFLAGS) options $*.c

------------------------------------------------------------------------
TagSubdirs(dirs):
    Generate rules to recursively create tags files.

    NamedTargetSubdirsRule(dirs,tag,"Tagging",/**/)

------------------------------------------------------------------------
TagsTarget():
    Generate rules to compute tags files for C source code.

	-> CTAGS RM.

    tags::
        $(CTAGS) -w *.[ch]
        $(CTAGS) -xw *.[ch] > tags

    local_clobber::
        $(RM) tags

------------------------------------------------------------------------
YaccRule():
    This is the rule which is used to build a .c file from a .y file.

    AddSuffix(.y)
    |once _YaccRule_
    .y.c:
        $(YACC) $(JYFLAGS) $<
        $(MV) y.tab.c $@

    -once

------------------------------------------------------------------------
