#
# /+\
# +\	Copyright 1993, 1995 Christopher Seiwald.
# \+/
#
# This file is part of Jam - see jam.c for Copyright information.
#
#
# JAMBASE - jam 2.1 ruleset providing make(1)-like functionality
#
# Supports UNIX, NT, and VMS.
#
# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST
# 04/18/94 (seiwald) - use 'default =' when setting OS specific vars
# 04/21/94 (seiwald) - do RmTemps together
# 05/05/94 (seiwald) - all supported C compilers support -o: relegate
#		       RELOCATE as an option; set Ranlib to "" to disable it
# 06/01/94 (seiwald) - new 'actions existing' to do existing sources
# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS
# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS
# 09/19/94 (seiwald) - LinkLibraries and Undefs now append
#		     - Rule names downshifted.
# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile.
# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files.
# 01/08/95 (seiwald) - Shell now handled with awk, not sed
# 01/09/95 (seiwald) - Install* now take dest directory as target
# 01/10/95 (seiwald) - All entries sorted.
# 01/10/95 (seiwald) - NT support moved in, with LauraW's help.  
# 01/10/95 (seiwald) - VMS support moved in.
# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added.
# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE.
# 02/08/95 (seiwald) - SubDir works on VMS.
# 02/14/95 (seiwald) - MkDir and entourage.
# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves.
# 07/10/95 (taylor) - Support for Microsoft C++.
# 11/21/96 (peterk) - Support for BeOS
# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client)
# Special targets defined in this file:
#
# all		- parent of first, shell, files, lib, exe
# first		- first dependent of 'all', for potential initialization
# shell		- parent of all Shell targets 
# files		- parent of all File targets
# lib		- parent of all Library targets
# exe		- parent of all Main targets
# dirs		- parent of all MkDir targets
# clean		- removes all Shell, File, Library, and Main targets
# uninstall	- removes all Install targets
#	
# Rules defined by this file:
#
# as obj.o : source.s ;			.s -> .o
# Bulk dir : files ;			populate directory with many files
# Cc obj.o : source.c ;			.c -> .o
# C++ obj.o : source.cc ;		.cc -> .o
# Clean clean : sources ;		remove sources with 'jam clean'
# File dest : source ;			copy file
# Fortran obj.o : source.f ;		.f -> .o
# GenFile source.c : program args ;	make custom file
# Hardlink target : source ;		make link from source to target
# HdrRule source : headers ;		handle #includes
# InstallInto dir : sources ;		install any files
# InstallBin dir : sources ;		install binaries
# InstallLib dir : sources ;		install files
# InstallFile dir : sources ;		install files
# InstallMan dir : sources ;		install man pages
# InstallShell dir : sources ;		install shell scripts
# Lex source.c : source.l ;		.l -> .c
# Library lib : source ;		archive library from compiled sources
# LibraryFromObjects lib : objects ;	archive library from objects
# LinkLibraries images : libraries ;	bag libraries onto Mains
# Main image : source ;			link executable from compiled sources
# MainFromObjects image : objects ;	link executable from objects
# MkDir dir ;				make a directory, if not there
# Object object : source ;		compile object from source
# ObjectCcFlags source : flags ;	add compiler flags for object
# ObjectC++Flags source : flags ;	add compiler flags for object
# ObjectHdrs source : dirs ;		add include directories for object
# Objects sources ;			compile sources
# RmTemps target : sources ;		remove temp sources after target made
# Setuid images ;			mark executables Setuid
# SubDir TOP d1 d2 ... ;		start a subdirectory Jamfile
# SubDirCcFlags flags ;			add compiler flags until next SubDir
# SubDirC++Flags flags ;		add compiler flags until next SubDir
# SubDirHdrs dirs ;			add include dirs until next SubDir
# SubInclude TOP d1 d2 ... ;		include a subdirectory Jamfile
# Shell exe : source ;			make a shell executable
# Undefines images : symbols ;		save undef's for linking
# UserObject object : source ;		handle unknown suffixes for Object
# Yacc source.c : source.y ;		.y -> .c
#
# Utility rules that have no side effects:
#
# makeSubDir var : d1 d2 ... ;		$(var) = path to root
# addDirName var : d1 d2 ... ;		$(var) += path from root to dir
# makeDirName var : d1 d2 ... ;		$(var) = path from root to dir
# makeGrist var : d1 d2 ... ;		$(var) = grist form of dir
# makeGristedName var : value ;		$(var) = $(value:G=$(SOURCE_GRIST))
# makeCommon var1 : var2 ;		strip common initial elements
# makeRelPath var d1 : d2 ;		$(var) = rel path from d1 to d2
# makeSuffixed var $(SUF) : f1 f2 ... ; $(var) = $(>) with suffixes
# makeString var : value ... ;          $(var) = contatenated values
#
# Brief review of the jam language:
#
# Statements:
#	rule RULE - statements to process a rule
#	actions RULE - system commands to carry out target update
#
# Modifiers on actions:
#	together - multiple instances of same rule on target get executed
#		   once with their sources ($(>)) concatenated
#	updated - refers to updated sources ($(>)) only
#	ignore - ignore return status of command
#	quietly - don't trace its execution unless verbose
#	piecemeal - iterate command each time with a small subset of $(>)
#	existing - refers to currently existing sources ($(>)) only
#
# Special rules:
#	ALWAYS - always build a target
#	DEPENDS - builds the dependency graph
#	ECHO - blurt out targets on stdout
#	EXIT - blurt out targets and exit
#	INCLUDES - marks sources as headers for target (a codependency)
#	NOCARE - don't panic if the target can't be built
#	NOUPDATE - create the target if needed but never update it 
#	NOTFILE - ignore the timestamp of the target (it's not a file)
#	TEMPORARY - target need not be present if sources haven't changed
#
# Special variables set by jam:
#	$(<) - targets of a rule (to the left of the :)
#	$(>) - sources of a rule (to the right of the :)
#	$(UNIX) - true on UNIX
#	$(VMS) - true on VMS
#	$(NT) - true on NT
#	$(OS) - name of OS - varies wildly
#	$(JAMVERSION) - version number (2.1)
#
# Special variables used by jam:
#	SEARCH - where to find something (used during binding and actions)
#	LOCATE - where to plop something not found with SEARCH
#	HDRRULE - rule to call to handle include files
#	HDRSCAN - egrep regex to extract include files
#
# Special targets:
#	all - default if none given on command line
#
# Initialize variables
#
# "default =" - set only if unset
OSFULL = $(OS)$(OSPLAT)$(OSVER) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
#
# OS specific variable settings
#
switch $(OS)
{
case AIX :	LINKLIBS default = -lbsd ;
case DGUX :	RANLIB default = "" ; RELOCATE = true ;
case HPUX :	RANLIB default = "" ;
		INSTALL default = "" ;
case INTERIX :	RANLIB default = "" ;
		JAMSHELL default = "sh -c" ;
		CC default = gcc ;
case IRIX :	RANLIB default = "" ;
		INSTALL default = "" ;
case MVS :	RANLIB default = "" ; 
case NEXT :	AR default = libtool -o ;
		RANLIB default = "" ;
case MACOSX : AR default = libtool -o ;
              RANLIB default = "" ;
              C++ default = c++ ;
              MANDIR default = /usr/local/share/man ;
case NCR :	RANLIB default = "" ;
		INSTALL default = "" ;
case PTX :	RANLIB default = "" ;
case QNX :	INSTALL default = "" ;
case SCO :	RANLIB default = "" ;
		INSTALL default = "" ; RELOCATE = true ;
case SINIX :	RANLIB default = "" ;
case SOLARIS :	RANLIB default = "" ;
		INSTALL default = "install" ;
		AR default = "/usr/ccs/bin/ar ru" ;
case UNIXWARE :	RANLIB default = "" ; RELOCATE = true ;
}
#if $(OS) = SUNOS && $(TZ)
#{
#	Echo Warning: you are running the SunOS jam on Solaris. ;
#}
if $(UNIX)
{
	if $(OS) = QNX 
	{
	AR		default = wlib ;
	CC		default = cc ;
	CCFLAGS		default = -Q ;	# quiet
	C++		default = $(CC) ;
	C++FLAGS	default = -Q ;	# quiet
	LINK		default = $(CC) ;
	LINKFLAGS	default = -Q ;	# quiet
	NOARSCAN	default = true ;
	RANLIB		default = "" ;
	}
	else if $(OS) = BEOS && $(METROWERKS)
	{
	AR		default = mwld -xml -o ;
	BINDIR		default = /boot/bin ;
	CC		default = mwcc ;
	CCFLAGS		default = -nosyspath ;
	C++		default = $(CC) ;
	C++FLAGS	default = -nosyspath ;
	FORTRAN		default = "" ;
	LIBDIR		default = /boot/develop/libraries ;
	LINK		default = mwld ;
	LINKFLAGS	default = "" ;
	LEX		default = "" ;
	MANDIR		default = /boot/documentation/"Shell Tools"/HTML ;
	NOARSCAN	default = true ;
	RANLIB		default = "" ;	
	STDHDRS		default = /boot/develop/headers/posix ;
	YACC		default = "" ;
	YACCFLAGS	default = "" ;
	YACCFILES	default = "" ;
	}
	else if $(OS) = BEOS 
	{
	BINDIR		default = /boot/bin ;
	CC		default = gcc ;
	C++		default = $(CC) ;
	FORTRAN		default = "" ;
	LIBDIR		default = /boot/develop/libraries ;
	LINK		default = gcc ;
	LINKLIBS	default = -lnet ;
	LEX		default = "" ;
	NOARSCAN	default = true ;
	RANLIB		default = "" ;	
	STDHDRS		default = /boot/develop/headers/posix ;
	YACC		default = "" ;
	YACCFLAGS	default = "" ;
	YACCFILES	default = "" ;
	}
	else if $(OS) = AMIGA
	{
	CC				default = gcc ;
	YACC			default = bison ;
	YACCFLAGS	default = -d ;
	YACCFILES	default = y.tab ;
	}
	AR		default = ar ru ;
	AS		default = as ;
	AWK		default = awk ;
	ASFLAGS		default = ;
	BINDIR		default = /usr/local/bin ;
	C++		default = gcc ;
	C++FLAGS	default = ;
	CC		default = cc ;
	CCFLAGS		default = ;
	CP		default = cp ;
	CHMOD		default = chmod ;
	DOT		default	= . ;
	DOTDOT		default	= .. ;
	EXEMODE		default = 711 ;
	FILEMODE	default = 644 ;
	FORTRAN		default = f77 ;
	FORTRANFLAGS	default = ;
	HDRS		default = ;
	INSTALL		default = install -c ;
	LEX		default = lex ;
	LIBDIR		default = /usr/local/lib ;
	LINK		default = $(CC) ;
	LINKFLAGS	default = $(CCFLAGS) ;
	LINKLIBS	default = ;
	LN		default = ln ;
	MANDIR		default = /usr/local/man ;
	MKDIR		default = mkdir ;
	MV		default = mv -f ;
	OPTIM		default = -O ;
	RANLIB		default = ranlib ;
	RCP		default = rcp ;
	RSH		default = rsh ;
	RM		default = rm -f ;
	SED		default = sed ;
	SHELLHEADER	default = "#!/bin/sh" ;
	SHELLMODE	default = 755 ;
	SLASH		default = / ;
	STDHDRS		default = /usr/include ;
	SUFLIB		default = .a ;
	SUFOBJ		default = .o ;
	SUFEXE		default = "" ;
	UNDEFFLAG	default = "-u _" ;
	YACC		default = yacc ;
	YACCFLAGS	default = -d ;
	YACCFILES	default = y.tab ;
}
else if $(NT)
{
	AWK		default = awk ;
	CHMOD		default = chmod ;
    	CP		default = copy ;
	DOT		default	= . ;
	DOTDOT		default	= .. ;
	EXEMODE		default = 711 ;
	FILEMODE	default = 644 ;
	MKDIR		default = mkdir ;
	MV		default = mv -f ;
	OS			= NT ;		# replace Windows_NT
	RCP		default = rcp ;
	RSH		default = rsh ;
    	RM		default = del /f/q ;
	SED		default = sed ;
    	SLASH		default = \\ ;
    	SUFLIB		default = .lib ;
    	SUFOBJ		default = .obj ;
    	SUFEXE		default = .exe ;
     
    if $(BCCROOT)
    {
	ECHO "Compiler is Borland C++" ;
	AR		default = tlib ;
	ARFLAGS		default = /C /P64 ;
	CC		default = bcc32 ;
	CCFLAGS		default = -v -w- -DNT ;
	C++		default = bcc32 ;
	C++FLAGS	default = -v -w- ;
	LINK		default = $(CC) ;
	LINKFLAGS	default = $(CCFLAGS) ;
	STDLIBPATH	default = $(BCCROOT)\\lib ;
	STDHDRS		default = $(BCCROOT)\\include ;
	NOARSCAN	default = true ;
    }
    else if $(MSVC)
    {
	ECHO "Compiler is Microsoft Visual C++ 16 bit" ;
	AR		default = lib /nologo ;
	CC		default = cl /nologo ;
	CCFLAGS		default = /D \"WIN\" ;
	C++		default = $(CC) ;
	C++FLAGS	default = $(CCFLAGS) ;
	LINK		default = $(CC) ;
	LINKFLAGS	default = $(CCFLAGS) ;
	LINKLIBS	default = 
				#$(MSVC)\\lib\\advapi32.lib
				#$(MSVC)\\lib\\libcmt.lib
				$(MSVC)\\lib\\mlibce.lib
				#$(MSVC)\\lib\\slibce.lib
				$(MSVC)\\lib\\oldnames.lib
				#$(MSVC)\\lib\\kernel32.lib 
				;
	LINKLIBS	default = ;
	NOARSCAN	default = true ;
	OPTIM		default =  ;
	STDHDRS		default = $(MSVC)\\include ;
	UNDEFFLAG	default = "/u _" ;
    }
    else if $(MSVCNT)
    {
	ECHO "Compiler is Microsoft Visual C++" ;
	AR		default = lib ;
	AS		default = masm386 ;
	CC		default = cl /nologo ;
	CCFLAGS		default = ;
	C++		default = $(CC) ;
	C++FLAGS	default = $(CCFLAGS) ;
	LINK		default = link ;
	LINKFLAGS	default = ;
	LINKLIBS	default = $(MSVCNT)\\lib\\advapi32.lib
				$(MSVCNT)\\lib\\libc.lib
				$(MSVCNT)\\lib\\oldnames.lib
				$(MSVCNT)\\lib\\kernel32.lib ;
	OPTIM		default =  ;
	STDHDRS		default = $(MSVCNT)\\include ;
	UNDEFFLAG	default = "/u _" ;
    }
    else
    {
	EXIT On NT, set BCCROOT, MSVCNT, or MSVC to the root of the
		Borland or Microsoft directories. ;
    }
}
else if $(OS2)
{
	WATCOM		default = $(watcom) ;
	
    	CP		default = copy ;
	DOT		default	= . ;
	DOTDOT		default	= .. ;
	MKDIR		default = mkdir ;
    	MV		default = move ;
    	RM		default = del /f ;
	SED		default = sed ;
    	SLASH		default = \\ ;
    	SUFLIB		default = .lib ;
    	SUFOBJ		default = .obj ;
    	SUFEXE		default = .exe ;
     
    if ! $(WATCOM)
    {
	EXIT On OS2, set WATCOM to the root of the Watcom directory. ;
    }
	ECHO "OS2 compiler is Watcom." ;
	AR		default = wlib ;
	CC		default = wcc386 ;
	CCFLAGS		default = /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
	C++		default = wpp386 ;
	C++FLAGS	default = $(CCFLAGS) ;
	LINK		default = wcl386 ;
	LINKFLAGS	default = /zq ; # zq=quiet
	LINKLIBS	default = ;
	NOARSCAN	default = true ;
	OPTIM		default = ;
	STDHDRS		default = $(WATCOM)\\h ;
	UNDEFFLAG	default = "/u _" ;
}
else if $(VMS)
{
	AS		default = as ;
	CC		default = cc ;
	CCFLAGS		default = ;
	CP		default = copy/replace ;
	CRELIB		default = true ;
	DOT		default	= [] ;
	DOTDOT		default	= [-] ;
	EXEMODE		default = (w:e) ;
	FILEMODE	default = (w:r) ;
	HDRS		default = ;
	LEX		default = lex ;
	LINK		default = link ;
	LINKFLAGS	default = ;
	LINKLIBS	default = ;
	MV		default = rename ;
	OPTIM		default = ;
	RM		default = delete ;
	RUNVMS		default = mcr ;
	SED		default = sed ;
	SHELLMODE	default = (w:er) ;
	SLASH		default = . ;
	STDHDRS		default = decc$library_include ;
	SUFLIB		default = .olb ;
	SUFOBJ		default = .obj ;
	SUFEXE		default = .exe ;
	switch $(OS) 
	{
	case OPENVMS : CCFLAGS default = /stand=vaxc ;
	case VMS     : LINKLIBS default = sys$library:vaxcrtl.olb/lib ;
	}
}
else if $(MAC)
{
	CW		default = "{CW}" ;
	CWMAC		default = "$(CW):MacOS Support" ;
	CWMSL		default = "$(CW):Metrowerks Standard Library" ;
	CWGUSI		default = "{CWGUSI}" ;
	CC		default = mwcppc ;
	CCFLAGS		default = -eol -w off ;
	C++		default = mwcppc ;
	C++FLAGS	default = -eol -w off ;
	CP		default = copy ;
	DOT		default = ":" ;
	DOTDOT		default = "::" ;
	HDRS		default = "$(CWGUSI):include"
				  "$(CWMAC):Headers:Universal Headers"
				  "$(CWMAC):Headers:System Extras Headers:MPW Extras"
				  "$(CWMSL):MSL C:MSL Common:Public Includes"
				  "$(CWMSL):MSL C:MSL Mac:Public Includes" ;
				  
	LINK		default = mwlinkppc ;
	LINKFLAGS	default = -mpwtool -warn ;
	LINKLIBS	default = "$(CWGUSI):Lib:GUSIMPW.Lib.PPC"
				  "$(CWGUSI):Lib:MSLGUSI.Lib.PPC"
				  "$(CWMAC):Libraries:MacOS Common:Interfacelib"
				  "$(CWMAC):Libraries:MacOS PPC:PPCToolLibs.o"
				  "$(CWMAC):Libraries:MacOS Common:PLStringFuncs Glue:PLStringFuncsPPC.lib"
				  "$(CWMAC):Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib"
				  "$(CWMSL):MSL C:Bin:MSL C.PPC MPW(NL).Lib"
				  "$(CWMAC):Libraries:MacOS Common:Mathlib" ;
				
	MKDIR		default = newfolder ;
	MV		default = rename ;
	NOARSCAN	default = true ;
	OPTIM		default = ;
	RM		default = delete ;
	SLASH		default = ":" ;
	STDHDRS		default = ; #$(MWCIncludes) ;
	SUFLIB		default = .lib ;
	SUFOBJ		default = .o ;
	SUFEXE		default = "" ;
	NOARSCAN	default = true ;
}
# 
# Define some MS-specific commands for MS-specific actions (which
# are not yet added to Jambase)
#
if $(NT) || $(OS2)
{
	MSLIB 		default = lib ;
	MSLINK		default = link ;
	MSIMPLIB 	default = implib ;
	MSRC		default = rc ;
}
JAMFILE		default = Jamfile ;
JAMRULES	default = Jamrules ;
HDRPATTERN = "^[ 	]*#[ 	]*include[ 	]*[<\"](.*)[\">].*$" ;
#
# Base dependencies - first for "bootstrap" kinds of rules
#
DEPENDS all : shell files lib exe obj ;
DEPENDS all shell files lib exe obj : first ;
NOTFILE all first shell files lib exe obj dirs clean uninstall ;
ALWAYS clean uninstall ;
#
# Rules
#
rule As
{
	DEPENDS $(<) : $(>) ;
	ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
}
rule Bulk
{
	local i ;
	for i in $(>)
	{
	    File $(i:D=$(<)) : $(i) ;
	}
}
rule Cc
{
	local _h ;
	DEPENDS $(<) : $(>) ;
	# Just to clarify here: this sets the per-target CCFLAGS to
	# be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
	CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
	# If the compiler's -o flag doesn't work, relocate the .o
	if $(RELOCATE)
	{
	    CcMv $(<) : $(>) ;
	}
	_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
	if $(VMS) && $(_h)
	{
	    SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ;
	}
	else if $(MAC) && $(_h)
	{
	    local _i _j ;
	    _j = $(_h[1]) ;
	    for _i in $(_h[2-])
	    {
	    	_j = $(_j),$(_i) ;
	    }
	    MACINC on $(<) = \"$(_j)\" ;
	}
}
rule C++
{
	local _h ;
	DEPENDS $(<) : $(>) ;
	C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;
	if $(RELOCATE)
	{
	    CcMv $(<) : $(>) ;
	}
	_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
	if $(VMS) && $(_h)
	{
	    SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ;
	}
	else if $(MAC) && $(_h)
	{
	    local _i _j ;
	    _j = $(_h[1]) ;
	    for _i in $(_h[2-])
	    {
	    	_j = $(_j),$(_i) ;
	    }
	    MACINC on $(<) = \"$(_j)\" ;
	}
}
rule File
{
	DEPENDS files : $(<) ;
	DEPENDS $(<) : $(>) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
	MODE on $(<) = $(FILEMODE) ;
	Chmod $(<) ;
}
rule Fortran
{
	DEPENDS $(<) : $(>) ;
}
rule GenFile 
{
	local s ;
	makeGristedName s : $(<) ;
	Depends $(s) : $(>[1]:S=$(SUFEXE)) $(>[2-]) ;
	GenFile1 $(s) : $(>[1]:S=$(SUFEXE)) $(>[2-]) ;
	Clean clean : $(s) ;
}
rule GenFile1
{
	MakeLocate $(<) : $(LOCATE_SOURCE) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
}
rule HardLink
{
	DEPENDS files : $(<) ;
	DEPENDS $(<) : $(>) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
}
rule HdrRule
{
	# HdrRule source : headers ;
	# N.B.	This rule is called during binding, potentially after
	# the fate of many targets has been determined, and must be
	# used with caution: don't add dependencies to unrelated
	# targets, and don't set variables on $(<).
	# Tell Jam that anything depending on $(<) also depends on $(>),
	# set SEARCH so Jam can find the headers, but then say we don't
	# care if we can't actually find the headers (they may have been
	# within ifdefs),
	local s ;
	if $(HDRGRIST) 
	{ 
	    s = $(>:G=$(HDRGRIST)) ;
	} else { 
	    s = $(>) ; 
	}
	INCLUDES $(<) : $(s) ;
	SEARCH on $(s) = $(HDRSEARCH) ;
	NOCARE $(s) ;
	# Propagate on $(<) to $(>)
	HDRSEARCH on $(s) = $(HDRSEARCH) ;
	HDRSCAN on $(s) = $(HDRSCAN) ;
	HDRRULE on $(s) = $(HDRRULE) ;
	HDRGRIST on $(s) = $(HDRGRIST) ;
}
rule InstallInto
{
	local i t ;
	t = $(>:G=installed) ;
	DEPENDS install : $(t) ;
	DEPENDS $(t) : $(>) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
	MakeLocate $(t) : $(<) ;
	# Arrange for jam uninstall
	Clean uninstall : $(t) ;
	for i in $(>)
	{
	    Install $(i:G=installed) : $(i) ;
	}
	if ! $(INSTALL)
	{
	    Chmod $(t) ;
	    if $(OWNER) { Chown $(t) ; OWNER on $(t) = $(OWNER) ; }
	    if $(GROUP) { Chgrp $(t) ; GROUP on $(t) = $(GROUP) ; }
	}
}
rule InstallBin
{
	InstallInto $(<) : $(>) ;
	MODE on $(>:G=installed) = $(EXEMODE) ;
}
rule InstallFile
{
	InstallInto $(<) : $(>) ;
	MODE on $(>:G=installed) = $(FILEMODE) ;
}
rule InstallLib
{
	InstallInto $(<) : $(>) ;
	MODE on $(>:G=installed) = $(FILEMODE) ;
}
rule InstallMan
{
	# Really this just strips the . from the suffix
	local i s d ;
	for i in $(>)
	{
	    switch $(i:S)
	    {
	    case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
	    case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
	    case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
	    case .n : s = n ; case .man : s = 1 ;
	    }
	    d = man$(s) ;
	    InstallInto $(d:R=$(<)) : $(i) ;
	}
	MODE on $(>:G=installed) = $(FILEMODE) ;
}
rule InstallShell
{
	InstallInto $(<) : $(>) ;
	MODE on $(>:G=installed) = $(SHELLMODE) ;
}
rule Lex
{
	DEPENDS $(<) : $(>) ;
	MakeLocate $(<) : $(LOCATE_SOURCE) ;
	Clean clean : $(<) ;
}
rule Library
{
	LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
	Objects $(>) ;
}
rule LibraryFromObjects
{
	local i l s ;
	# Add grist to file names
	makeGristedName s : $(>) ;
	# library depends on its member objects
	l = $(<:S=$(SUFLIB)) ;
	if $(KEEPOBJS)
	{
	    DEPENDS obj : $(s) ;
	}
	else
	{
	    DEPENDS lib : $(l) ;
	}
	# Set LOCATE for the library and its contents.  The bound
	# value shows up as $(NEEDLIBS) on the Link actions.
	# For compatibility, we only do this if the library doesn't
	# already have a path.
	if ! $(l:D)
	{
	    MakeLocate $(l) $(l)($(s:BS)) : $(LOCATE_TARGET) ;
	}
	if $(NOARSCAN) 
	{ 
	    # If we can't scan the library to timestamp its contents,
	    # we have to just make the library depend directly on the
	    # on-disk object files.  
	    DEPENDS $(l) : $(s) ;
	}
	else
	{
	    # If we can scan the library, we make the library depend
	    # on its members and each member depend on the on-disk
	    # object file.
	    DEPENDS $(l) : $(l)($(s:BS)) ;
	    for i in $(s)
	    {
		DEPENDS $(l)($(i:BS)) : $(i) ;
	    }
	}
	Clean clean : $(l) ;
	if $(CRELIB) { CreLib $(l) : $(s[1]) ; }
	Archive $(l) : $(s) ;
	if $(RANLIB) { Ranlib $(l) ; }
	# If we can't scan the library, we have to leave the .o's around.
	if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(l) : $(s) ; }
}
rule Link
{
	MODE on $(<) = $(EXEMODE) ;
	Chmod $(<) ;
}
rule LinkLibraries
{
	local t ;
	# make library dependencies of target
	# set NEEDLIBS variable used by 'actions Main'
	if $(<:S)
	{
	    t = $(<) ;
	} else {
	    t = $(<:S=$(SUFEXE)) ;
	}
	DEPENDS $(t) : $(>:S=$(SUFLIB)) ;
	NEEDLIBS on $(t) += $(>:S=$(SUFLIB)) ;
}
rule Main
{
	MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
	Objects $(>) ;
}
rule MainFromObjects
{
	local s t ;
	# Add grist to file names
	makeGristedName s : $(>) ;
	makeSuffixed t $(SUFEXE) : $(<) ;
	if $(t) != $(<)
	{
	    DEPENDS $(<) : $(t) ;
	    NOTFILE $(<) ;
	}
	# make compiled sources a dependency of target
	DEPENDS exe : $(t) ;
	DEPENDS $(t) : $(s) ;
	MakeLocate $(t) : $(LOCATE_TARGET) ;
	Clean clean : $(t) ;
	Link $(t) : $(s) ;
}
rule MakeLocate
{
	if $(>)
	{
	    LOCATE on $(<) = $(>) ;
	    Depends $(<) : $(>[1]) ;
	    MkDir $(>[1]) ;
	}
}
rule MkDir
{
	if $(<) != $(DOT) && ! $($(<)-mkdir) 
	{
	    local s ;
	    # Cheesy gate to prevent multiple invocations on same dir
	    # MkDir1 has the actions 
	    # If dir exists, don't update it
	    # Arrange for jam dirs
	    $(<)-mkdir = true ;
	    MkDir1 $(<) ;
	    NOUPDATE $(<) ;
	    Depends dirs : $(<) ;
	    # Recursively make parent directories.
	    # $(<:P) = $(<)'s parent, & we recurse until root
	    s = $(<:P) ;
	    if $(NT)
	    {
	        switch $(s)
		{
		case *:   : s = ;
		case *:\\ : s = ;
		}
	    }
	    if $(s) && $(s) != $(<)
	    {
		Depends $(<) : $(s) ;
		MkDir $(s) ;
	    }
	    else if $(s)
	    {
	        NOTFILE $(s) ;
	    }
	}
}
rule Object
{
	local h ;
	# locate object and search for source, if wanted
	Clean clean : $(<) ;
	MakeLocate $(<) : $(LOCATE_TARGET) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
	# Save HDRS for -I$(HDRS) on compile.
	# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
	# in the .c file's directory, but generated .c files (from
	# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
	# different from $(SEARCH_SOURCE).
	HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
	# handle #includes for source: Jam scans for headers with
	# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
	# with the scanned file as the target and the found headers
	# as the sources.  HDRSEARCH is the value of SEARCH used for
	# the found header files.  Finally, if jam must deal with 
	# header files of the same name in different directories,
	# they can be distinguished with HDRGRIST.
	# $(h) is where cc first looks for #include "foo.h" files.
	# If the source file is in a distant directory, look there.
	# Else, look in "" (the current directory).
	if $(SEARCH_SOURCE)
	{
	    h = $(SEARCH_SOURCE) ;
	}
	else
	{
	    h = "" ;
	}
	HDRRULE on $(>) = HdrRule ;
	HDRSCAN on $(>) = $(HDRPATTERN) ;
	HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;
	HDRGRIST on $(>) = $(HDRGRIST) ;
	# if source is not .c, generate .c with specific rule
	switch $(>:S)
	{
	    case .asm : As $(<) : $(>) ;
	    case .c :	Cc $(<) : $(>) ;
	    case .C :	C++ $(<) : $(>) ;
	    case .cc :	C++ $(<) : $(>) ;
	    case .cpp : C++ $(<) : $(>) ;
	    case .f :	Fortran $(<) : $(>) ;
	    case .l :	Cc $(<) : $(<:S=.c) ;
			Lex $(<:S=.c) : $(>) ;
	    case .s :	As $(<) : $(>) ;
	    case .y :	Cc $(<) : $(<:S=.c) ;
			Yacc $(<:S=.c) : $(>) ;
	    case * :	UserObject $(<) : $(>) ;
	}
}
rule ObjectCcFlags
{
	local s ;
	# Add grist to file names
	makeGristedName s : $(<:S=$(SUFOBJ)) ;
	CCFLAGS on $(s) += $(>) ;
}
rule ObjectC++Flags
{
	local s ;
	# Add grist to file names
	makeGristedName s : $(<:S=$(SUFOBJ)) ;
	C++FLAGS on $(s) += $(>) ;
}
rule ObjectHdrs
{
	local s ;
	# Add grist to file names
	makeGristedName s : $(<:S=$(SUFOBJ)) ;
	HDRS on $(s) += $(>) ;
}
rule Objects
{
	local i s ;
	# Add grist to file names
	makeGristedName s : $(<) ;
	for i in $(s)
	{
		Object $(i:S=$(SUFOBJ)) : $(i) ;
		DEPENDS obj : $(i:S=$(SUFOBJ)) ;
	}
}
rule RmTemps
{
	TEMPORARY $(>) ;
}
rule Setuid
{
	local t ;
	if $(<:S)
	{
	    t = $(<) ;
	} else {
	    t = $(<:S=$(SUFEXE)) ;
	}
	MODE on $(t) = 4711 ;
}
rule Shell
{
	DEPENDS shell : $(<) ;
	DEPENDS $(<) : $(>) ;
	SEARCH on $(>) = $(SEARCH_SOURCE) ;
	MODE on $(<) = $(SHELLMODE) ;
	Clean clean : $(<) ;
	Chmod $(<) ;
}
rule SubDir
{
	local r s ;
	#
	# SubDir TOP d1 [ ... ]
	#
	# This introduces a Jamfile that is part of a project tree 
	# rooted at $(TOP).  It (only once) includes the project-specific
	# rules file $(TOP)/Jamrules and then sets search & locate stuff.
	#
	# If the variable $(TOPRULES) is set (where TOP is the first arg 
	# to SubDir), that file is included instead of $(TOP)/Jamrules.
	#
	# d1 ... are the directory elements that lead to this directory 
	# from $(TOP).  We construct the system dependent path from these
	# directory elements in order to set search&locate stuff.
	# 
	if ! $($(<[1]))
	{
	    if ! $(<[1])
	    {
		EXIT SubDir syntax error ;
	    }
	    makeSubDir $(<[1]) : $(<[2-]) ;
	}
	#
	# If $(TOP)/Jamrules hasn't been included, do so.
	#
	if ! $($(<[1])-included)
	{
	    # Gated entry.
	    $(<[1])-included = TRUE ;
	    # File is $(TOPRULES) or $(TOP)/Jamrules.
	    r = $($(<[1])RULES) ;
	    if ! $(r)
	    {
		r = $(JAMRULES:R=$($(<[1]))) ;
	    }
	    # Include it.
	    include $(r) ;
	}
	# Get path to current directory from root using makeSubDir.
	# Save dir tokens for other potential uses.
	makeDirName s : $(<[2-]) ;
	SUBDIR = $(s:R=$($(<[1]))) ;
        SUBDIR_TOKENS = $(<[2-]) ;
	# Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
	# These can be reset if needed.	 For example, if the source
	# directory should not hold object files, LOCATE_TARGET can
	# subsequently be redefined.
	SEARCH_SOURCE = $(SUBDIR) ;
	LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
	LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
	makeGrist SOURCE_GRIST : $(<[2-]) ;
	# Reset per-directory ccflags, hdrs
	SUBDIRCCFLAGS = ;
	SUBDIRC++FLAGS = ;
	SUBDIRHDRS = ;
}
rule SubDirCcFlags
{
	SUBDIRCCFLAGS += $(<) ;
}
rule SubDirC++Flags
{
	SUBDIRC++FLAGS += $(<) ;
}
rule SubDirHdrs
{
	SUBDIRHDRS += $(<) ;
}
rule SubInclude
{
	local s ;
	# That's
	#	SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ]
	#
	# to include a subdirectory's Jamfile.
	if ! $($(<[1]))
	{
	    EXIT Top level of source tree has not been set with $(<[1]) ;
	}
	makeDirName s : $(<[2-]) ;
	
	include $(JAMFILE:D=$(s):R=$($(<[1]))) ;
}
rule Undefines
{
	local t ;
	if $(<:S)
	{
	    t = $(<) ;
	} else {
	    t = $(<:S=$(SUFEXE)) ;
	}
	UNDEFS on $(t) += $(UNDEFFLAG)$(>) ;
}
rule UserObject
{
	EXIT "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
}
rule Yacc
{
	local h ;
	h = $(<:BS=.h) ;
	# Some places don't have a yacc.
	MakeLocate $(<) $(h) : $(LOCATE_SOURCE) ;
	if $(YACC)
	{
	    DEPENDS $(<) $(h) : $(>) ;
	    Yacc1 $(<) $(h) : $(>) ;
	    Clean clean : $(<) $(h) ;
	}
	# make sure someone includes $(h) else it will be
	# a deadly independent target
	INCLUDES $(<) : $(h) ;
}
#
# Utility rules; no side effects on these
#
rule makeString
{
	local _t ;
	$(<) = $(>[1]) ;
	for _t in $(>[2-])
	{
		$(<) = $($(<))$(_t) ;
	}
}
rule makeSubDir
{
	local _i _d ;
	# If $(>) is the path to the current directory, compute the
	# path (using ../../ etc) back to that root directory.
	# Sets result in $(<)
	if ! $(>[1]) 
	{
	    _d = $(DOT) ;
	} 
	else
	{
	    _d = $(DOTDOT) ;
	    for _i in $(>[2-])
	    {
		_d = $(_d:R=$(DOTDOT)) ;
	    }
	}
	$(<) = $(_d) ;
}
rule addDirName
{
	local _s _i ;
	# Turn individual elements in $(>) into a usable path.
	# Add result to $(<).
	if ! $(>)
	{
	    _s = $(DOT) ;
	}
	else if $(VMS)
	{
	    # This handles the following cases:
	    # 	a -> [.a]
	    # 	a b c -> [.a.b.c]
	    # 	x: -> x:
	    # 	x: a -> x:[a]
	    # 	x:[a] b -> x:[a.b]
	    switch $(>[1])
	    {
	    case *:* : _s = $(>[1]) ;
	    case \\[*\\] : _s = $(>[1]) ;
	    case * : _s = [.$(>[1])] ;
	    }
	    for _i in [.$(>[2-])]
	    {
		_s = $(_i:R=$(_s)) ;
	    }
	}
	else if $(MAC)
	{
	    _s = $(DOT) ;
	    
	    for _i in $(>)
	    {
	    	_s = $(_i:R=$(_s)) ;
	    }
	}
	else
	{
	    _s = $(>[1]) ; 
	    for _i in $(>[2-])
	    {
		_s = $(_i:R=$(_s)) ;
	    }
	}
	$(<) += $(_s) ;
}
rule makeDirName
{
	$(<) = ; addDirName $(<) : $(>) ;
}
rule makeGrist
{
	local _g _i ;
	# Turn individual elements in $(>) into grist.
	# Return result in $(<)
	_g = $(>[1]) ;
	for _i in $(>[2-])
	{
	    _g = $(_g)!$(_i) ;
	}
	$(<) = $(_g) ;
}
rule makeGristedName
{
	local _i _o ;
	# Produce name with grist in it, if SOURCE_GRIST is set.
	if ! $(SOURCE_GRIST)
	{
	    $(<) = $(>) ;
	}
	else 
	{
	    _o = ;
	    for _i in $(>)
	    {
		switch $(_i)
		{
		case *.h :	_o += $(_i) ;
		case * : 	_o += $(_i:G=$(SOURCE_GRIST)) ;
		}
	    }
	    $(<) = $(_o) ;
	}
}
rule makeCommon
{
	if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
	{
	    $(<) = $($(<)[2-]) ;
	    $(>) = $($(>)[2-]) ;
	    makeCommon $(<) : $(>) ;
	}
}
rule makeRelPath 
{
	local _l _r ;
	# first strip off common parts
	_l = $(<[2-]) ;
	_r = $(>) ;
	makeCommon _l : _r ;
	# now make path to root and path down
	makeSubDir _l : $(_l) ;
	makeDirName _r : $(_r) ;
	# Concatenate and save
	# XXX This should be better
	if $(_r) = $(DOT) {
	    $(<[1]) = $(_l) ;
	} else {
	    $(<[1]) = $(_r:R=$(_l)) ;
	}
}
rule makeSuffixed
{
   # E.g., "makeSuffixed s_exe $(SUFEXE) : yacc lex foo.bat ;"
   # sets $(s_exe) to (yacc,lex,foo.bat) on Unix and 
   # (yacc.exe,lex.exe,foo.bat) on NT.
	if $(<[2])
	{
	    local _i ;
	    $(<[1]) = ;
	    for _i in $(>)
	    {
		if $(_i:S)
		{
		    $(<[1]) += $(_i) ;
		}
		else
		{
		    $(<[1]) += $(_i:S=$(<[2])) ;
		}
	    }
	}
	else
	{
	    $(<[1]) = $(>) ;
	}
}
rule unmakeDir
{
    if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ 
    {
        unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;
    }
    else
    {
        $(<) = $(>) ;
    }
}
#
# Actions
#
if $(UNIX)
{
    if $(OS) = QNX 
    {
	actions together piecemeal Archive
	{
	$(AR) $(<) +-$(>) 
	}
    }
    else if $(OS) = BEOS && $(METROWERKS)
    {
	actions together Archive
	{
	$(AR) $(<) $(>)
	}
    }
    else
    {
	actions updated together piecemeal Archive
	{
	$(AR) $(<) $(>)
	}
    }
    actions As
    {
	$(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>)
    }
    if $(RELOCATE)
    {
	actions C++
	{
	$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>)
	}
    }
    else
    {
	actions C++
	{
	$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
	}
    }
    actions Cc
    {
	$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
    }
    if $(RELOCATE)
    {
	actions Cc
	{
	$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>)
	}
    }
    actions ignore CcMv
    {
	[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
    }
    actions Chgrp
    {
	chgrp $(GROUP) $(<)
    }
    actions Chmod
    {
	chmod $(MODE) $(<)
    }
    actions Chown
    {
	chown $(OWNER) $(<)
    }
    actions piecemeal together existing Clean
    {
	$(RM) $(>)
    }
    actions File
    {
	$(RM) $(<)
	$(CP) $(>) $(<)
    }
    actions GenFile1
    {
	$(>[1]) $(<) $(>[2-])
    }
    actions Fortran
    {
	$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
    }
    actions HardLink
    {
	$(RM) $(<) && $(LN) $(>) $(<)
    }
    if $(INSTALL)
    {
	actions Install
	{
	$(INSTALL) -m$(MODE) -o$(OWNER) -g$(GROUP) $(>) $(<)
	}
    }
    else
    {
	actions Install
	{
	$(CP) $(>) $(<) 
	}
    }
    actions Lex
    {
	$(LEX) $(>) && $(MV) lex.yy.c $(<)
    }
    actions Link bind NEEDLIBS
    {
	$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 
    }
    actions MkDir1
    {
	$(MKDIR) $(<)
    }
    actions together Ranlib
    {
	$(RANLIB) $(<)
    }
    actions quietly updated piecemeal together RmTemps
    {
	$(RM) $(>)
    }
    actions Shell
    {
	$(AWK) '
		NR == 1 { print "$(SHELLHEADER)" }
		NR == 1 && /^[#:]/ { next }
		/^##/ { next }
		{ print }
	' < $(>) > $(<)
    }
    actions Yacc1
    {
	$(YACC) $(YACCFLAGS) $(>) &&
	{
	    $(MV) $(YACCFILES).c $(<[1])
	    $(MV) $(YACCFILES).h $(<[2])
	}
    }
}
else if $(NT) || $(OS2)
{
    if $(BCCROOT)
    {
	actions C++
	{
	$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
	}
	actions Link bind NEEDLIBS
	{
	$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)
	}
	actions updated together piecemeal Archive
	{
	$(AR) $(ARFLAGS) $(<) -+$(>)
	}
	actions Cc
	{
	$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
        }
    }
    else if $(MSVC) 
    {
	actions updated together piecemeal Archive
	{
	$(AR) $(<) -+$(>) ;
	}
	actions Cc
	{
	$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>)
	}
	actions C++
	{
	$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>)
	}
	actions Link bind NEEDLIBS
	{
	$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
	}
    }
    else if $(MSVCNT)
    {
	actions updated together piecemeal Archive
	{
	if exist $(<) set _$(<:B)_=$(<)
	$(AR) /out:$(<) %_$(<:B)_% $(>)
	}
	actions As
	{
	$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
	}
	actions Cc
	{
	$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>)
	}
	actions C++
	{
	$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>)
	}
	actions Link bind NEEDLIBS
	{
	$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
	}
    }
    else if $(WATCOM)
    {
	actions together piecemeal Archive
	{
	$(AR) $(<) +-$(>) 
	}
	actions Cc
	{
	$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
	}
	actions C++
	{
	$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
	}
	actions Link bind NEEDLIBS
	{
	$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
	}
    }
    actions Chmod
    {
    }
    actions piecemeal together existing Clean
    {
	$(RM) $(>)
    }
    actions File
    {
	copy $(>) $(<)
    }
    actions GenFile1
    {
	$(>[1]) $(<) $(>[2-])
    }
    actions Install
    {
	copy $(>) $(<)
    }
    actions MkDir1
    {
	$(MKDIR) $(<)
    }
    actions quietly updated piecemeal together RmTemps
    {
	$(RM) $(>)
    }
    actions Shell
    {
	copy $(>) $(<)
    }
}
else if $(VMS)
{
    actions updated together piecemeal Archive 
    {
	lib/replace $(<) $(>[1]) ,$(>[2-])
    }
    actions Cc
    { 
	cc/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>) 
    }
    actions C++
    { 
	cxx/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) 
    }
    actions Chmod
    {
	set file/prot=$(MODE) $(<)
    }
    actions piecemeal together existing Clean
    {
	$(RM) $(>[1]);* ,$(>[2-]);*
    }
    actions together quietly CreLib
    {
       if f$search("$(<)") .eqs. "" then lib/create $(<)
    }
    actions File
    {
	copy $(>) $(<)
    }
    actions GenFile1
    {
	mcr $(>[1]) $(<) $(>[2-])
    }
    actions Install
    {
	copy $(>) $(<)
    }
    actions Lex
    {
	$(LEX) $(>) 
	$(MV) lex.yy.c $(<)
    }
    actions Link bind NEEDLIBS
    {
	$(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
    }
    actions MkDir1
    {
	create/dir $(<)
    }
    actions quietly updated piecemeal together RmTemps
    {
	$(RM) $(>[1]);* ,$(>[2-]);*
    }
    actions Shell
    {
	copy $(>) $(<)
    }
    actions Yacc1
    {
	$(YACC) $(YACCFLAGS) $(>)
	$(MV) $(YACCFILES).c $(<[1])
	$(MV) $(YACCFILES).h $(<[2])
    }
}
else if $(MAC)
{
    SP = " " ;
    actions together Archive 
    {
	$(LINK) -library -o $(<) $(>)
    }
    actions Cc
    {
	set MWCincludes $(MACINC)
	$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) 
    }
    actions C++
    { 
	set MWCincludes $(MACINC)
	$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) 
    }
    rule Chmod
    {
	# no chmod on mac - could setfile -l/-L to make rw/ro
    }
    actions piecemeal together existing Clean
    {
	$(RM) $(>)
    }
    actions File
    {
	copy $(>) $(<)
    }
    actions GenFile1
    {
	$(>[1]) $(<) $(>[2-])
    }
    actions Install
    {
	copy $(>) $(<)
    }
    actions Link bind NEEDLIBS
    {
	$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)"
    }
    actions MkDir1
    {
	$(MKDIR) $(<)
    }
    actions quietly updated piecemeal together RmTemps
    {
	$(RM) $(>)
    }
    actions Shell
    {
	copy $(>) $(<)
    }
}
#
# Backwards compatibility with jam 1, where rules were uppercased.
#
rule BULK { Bulk $(<) : $(>) ; }
rule FILE { File $(<) : $(>) ; }
rule HDRRULE { HdrRule $(<) : $(>) ; }
rule INSTALL { Install $(<) : $(>) ; }
rule LIBRARY { Library $(<) : $(>) ; }
rule LIBS { LinkLibraries $(<) : $(>) ; }
rule LINK { Link $(<) : $(>) ; }
rule MAIN { Main $(<) : $(>) ; }
rule SETUID { Setuid $(<) ; }
rule SHELL { Shell $(<) : $(>) ; }
rule UNDEFINES { Undefines $(<) : $(>) ; }
# Old INSTALL* didn't take dest directory.
rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
#
# Now include the user's Jamfile.
#
{
    if $(JAMFILE) { include $(JAMFILE) ; }
}