#
#  Shared definitions for building with JAM.
#
#  Target type:
#
#  StaticExecutable - an exe linked with static libraries
#  SharedExecutable - an exe linked with dynamic libraries
#  StaticLibrary    - a statically linked library
#  SharedLibrary    - a dynamically linked library, a dll, and its associated stub library
#  Clean            - a pseudo target which deletes all its dependents.
#
#  Most of the targets take 5 argument lists:
#  1. the name of the file to generate
#  2. a list of source files
#  3. a list of static libraries, dll export libs, and objects to link with
#  4. a list of dynamic libraries to copy into the local directory
#  5. an optional directory to dump the generated target into.
#

PLATFORM ?= $(JAMPLATFORM:L) ;
CURFLAV ?= debug ;

# include the actions files - but first we tell jam where they can be found:
SEARCH on script_dir = . scripts ../scripts ;
notfile script_dir ;

JAMWRAP = 21 $(COLUMNS:E=80) 20 ;

if ( $(PLATFORM) == win32 )
   on script_dir { include "jambase.win32" ; }
else
   on script_dir { include "jambase.linux" ; }

# this is the header pattern that matches both "" and <> includes.
# HDRPATTERN      = "#[\t ]*include[\t ]*[<\"]([^\">]*)[\">]" ;

# matches only "" includes
HDRPATTERN        = "#[\t ]*include[\t ]*[\"]([^\"]*)[\"]" ;

notfile all clean ;
always clean ;

# if this is set to true, then we automatically build a list of dependencies for 'all'
# until we see a group named all.
AUTOALL ?= true ;

# rules --------------------------------------------

rule InitDirs
{
   if ( $(INIT_DIRS_DONE) ) return ;
   INIT_DIRS_DONE = true ;
   
   BIN_DIR   = bin/$(PLATFORM)/$(CURFLAV)/ ;
   LIB_DIRS += $(BIN_DIR) $(LIB_DIRS)/$(BIN_DIR) ;
   
   # for generated headers that end up in the bin dir.
   INCLUDE_DIRS += $(BIN_DIR) ;

   ActionInitDirs ;
   
   SEARCH += . $(INCLUDE_DIRS) ; 
   
   # only search in directories that actually exist
   SEARCH    = $(SEARCH:A) ;
   LIB_DIRS  = $(LIB_DIRS:A) ;

   HDRRULE   = HeaderRule ;
   HDRSEARCH = $(SEARCH) ;
}

rule Group TARGET : SOURCES
{
   InitDirs ;
   
   if ( $(TARGET) == all ) 
   {
      AUTOALL = false ;
      cleardep all ; # remove any dependencies 'all' may have accumulated up to this point
   } else {
      if ( $(AUTOALL) == true ) depends all : $(TARGET) ;
   }
   
   if ( $(PLATFORM) == win32 )
      SOURCES =                          lib$(SOURCES:I="\.a"S=.lib) lib$(SOURCES:I="\.so"S=.dll) $(SOURCES:X="\.a"X="\.so") ;
   else
      SOURCES = $(SOURCES:I="\.exe"S="") lib$(SOURCES:I="\.lib"S=.a) lib$(SOURCES:I="\.dll"S=.so) $(SOURCES:X="\.exe"X="\.lib"X="\.dll") ;

   depends $(TARGET) : $(SOURCES) ;
}

rule StaticExecutable  TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   InitDirs ;
   
   TARGET = $(TARGET:B)$(EXE_SUFFIX) ;
   
   SOURCES = [ ExpandSources $(SOURCES) ] ;
   
   if ( $(AUTOALL) == true ) depends all : $(TARGET) ;
      
   if ( $(TARGET_DIR) ) TARGET_DIR = $(TARGET_DIR)/ ;
   else                 TARGET_DIR = $(BIN_DIR) ;
   LOCATE on $(TARGET)  = $(TARGET_DIR) ;
   CreateDirectory $(TARGET_DIR) ;
   CleanTarget $(TARGET) : $(TARGET_DIR) ;

   local OBJECTS ;
   if ( $(SOURCES) ) OBJECTS = [ ObjectSet $(TARGET) : $(SOURCES) : static ] ;
   
   LINKOBJS = [ GetLinkObjs $(LIBS) ] ;
   LINKLIBS = [ GetLinkLibs $(LIBS) $(DLLS) ] ;
   LINKDLLS = [ GetLinkDlls $(LIBS) ] ;
   COPYDLLS = [ GetCopyDlls $(DLLS) ] ;
   
   SEARCH on $(LINKLIBS) = $(LIB_DIRS) ;
   
   depends           $(TARGET) : $(TARGET_DIR) $(LINKOBJS) $(LINKLIBS) $(LINKDLLS) $(COPYDLLS) ;
   LinkExecutable    $(TARGET) : $(OBJECTS)    $(LINKOBJS) : $(LINKLIBS) ;
   ExternalDlls      $(TARGET) : $(COPYDLLS) : $(TARGET_DIR) ;
}

rule SharedExecutable  TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   InitDirs ;
   
   TARGET = $(TARGET:B)$(EXE_SUFFIX) ;
   
   SOURCES = [ ExpandSources $(SOURCES) ] ;
   
   if ( $(AUTOALL) == true ) depends all : $(TARGET) ;
   
   if ( $(TARGET_DIR) ) TARGET_DIR = $(TARGET_DIR)/ ;
   else                 TARGET_DIR = $(BIN_DIR) ;
   LOCATE on $(TARGET)  = $(TARGET_DIR) ;
   CreateDirectory $(TARGET_DIR) ;
   CleanTarget $(TARGET) : $(TARGET_DIR) ;

   local OBJECTS ;
   if ( $(SOURCES) ) OBJECTS = [ ObjectSet $(TARGET) : $(SOURCES) : shared ] ;
   
   LINKOBJS = [ GetLinkObjs $(LIBS) ] ;
   LINKLIBS = [ GetLinkLibs $(LIBS) $(DLLS) ] ;
   LINKDLLS = [ GetLinkDlls $(LIBS) ] ;
   COPYDLLS = [ GetCopyDlls $(DLLS) ] ;
   
   SEARCH on $(LINKLIBS) = $(LIB_DIRS) ;

   depends           $(TARGET) : $(TARGET_DIR) $(LINKOBJS) $(LINKLIBS) $(LINKDLLS) $(COPYDLLS) ;
   LinkExecutable    $(TARGET) : $(OBJECTS)    $(LINKOBJS) : $(LINKLIBS) ;
   ExternalDlls      $(TARGET) : $(COPYDLLS) : $(TARGET_DIR) ;
}

rule StaticLibrary     TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   InitDirs ;
   
   TARGET = $(LIB_PREFIX)$(TARGET:B)$(LIB_SUFFIX) ;
   
   SOURCES = [ ExpandSources $(SOURCES) ] ;
   
   if ( $(AUTOALL) == true ) depends all : $(TARGET) ;
   
   if ( $(TARGET_DIR) ) TARGET_DIR = $(TARGET_DIR)/ ;
   else                 TARGET_DIR = $(BIN_DIR) ;
   LOCATE on $(TARGET)  = $(TARGET_DIR) ;
   CreateDirectory $(TARGET_DIR) ;
   CleanTarget $(TARGET) : $(TARGET_DIR) ;

   local OBJECTS ;
   if ( $(SOURCES) ) OBJECTS = [ ObjectSet $(TARGET) : $(SOURCES) : static ] ;
   
   LINKOBJS = [ GetLinkObjs $(LIBS) ] ;
   LINKLIBS = [ GetLinkLibs $(LIBS) $(DLLS) ] ;
   LINKDLLS = [ GetLinkDlls $(LIBS) ] ;
   COPYDLLS = [ GetCopyDlls $(DLLS) ] ;
   
   SEARCH on $(LINKLIBS) = $(LIB_DIRS) ;
   
   depends           $(TARGET) : $(TARGET_DIR) $(LINKOBJS) $(LINKLIBS) $(LINKDLLS) $(COPYDLLS) ;
   LinkStaticLibrary $(TARGET) : $(OBJECTS)    $(LINKOBJS) : $(LINKLIBS) ;
   ExternalDlls      $(TARGET) : $(COPYDLLS) : $(TARGET_DIR) ;
}

rule SharedLibraryRaw     TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   InitDirs ;
   
   SOURCES = [ ExpandSources $(SOURCES) ] ;
   
   if ( $(AUTOALL) == true ) depends all : $(TARGET:X="\.lib$") ;
   
   if ( $(TARGET_DIR) ) TARGET_DIR = $(TARGET_DIR)/ ;
   else                 TARGET_DIR = $(BIN_DIR) ;
   LOCATE on $(TARGET)  = $(TARGET_DIR) ;
   CreateDirectory $(TARGET_DIR) ;
   CleanTarget $(TARGET) : $(TARGET_DIR) ;

   local OBJECTS ;
   if ( $(SOURCES) ) OBJECTS = [ ObjectSet $(TARGET) : $(SOURCES) : shared ] ;
      
   LINKOBJS = [ GetLinkObjs $(LIBS) ] ;
   LINKLIBS = [ GetLinkLibs $(LIBS) $(DLLS) ] ;
   LINKDLLS = [ GetLinkDlls $(LIBS) ] ;
   COPYDLLS = [ GetCopyDlls $(DLLS) ] ;
   
   SEARCH on $(LINKLIBS) = $(LIB_DIRS) ;
   
   depends           $(TARGET) : $(TARGET_DIR) $(LINKOBJS) $(LINKLIBS) $(LINKDLLS) $(COPYDLLS) ;
   LinkSharedLibrary $(TARGET) : $(OBJECTS)    $(LINKOBJS) : $(LINKLIBS) ;
   ExternalDlls      $(TARGET) : $(COPYDLLS) : $(TARGET_DIR) ;
}

rule SharedLibrary     TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   SharedLibraryRaw $(LIB_PREFIX)$(TARGET:B)$(DLL_SUFFIX) : $(SOURCES) : $(LIBS) : $(DLLS) : $(TARGET_DIR) ;
}

rule SharedLibraryNL   TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   SharedLibraryRaw $(LIB_PREFIX)$(TARGET:B)$(DLL_SUFFIX:X=".lib") : $(SOURCES) : $(LIBS) : $(DLLS) : $(TARGET_DIR) ;
}

rule FsmSharedLibrary TARGET : SOURCES : LIBS : DLLS : TARGET_DIR
{
   // roll the fsm into one .cpp source
   FsmRule  $(TARGET:B).cpp : $(SOURCES:I="\.fsm") ;
   
   // fsm shared libraries on windows may not actually have a .lib stub library
   SharedLibraryNL $(TARGET) : $(SOURCES:X="\.fsm") $(TARGET:B).cpp : $(LIBS) : $(DLLS) : $(TARGET_DIR) ;
}

rule Object TARGET : SOURCE : OBJ_SUBDIR : LOC_CCOPTS
{
   InitDirs ;
   
   if ( $(PLATFORM) == win32 )
      LOC_CCOPTS = "$(LOC_CCOPTS:N=\" \"0=\"\ \")" ;
   
   TARGET = <$(OBJ_SUBDIR)>$(TARGET:B)$(OBJ_SUFFIX) ;
   LOCATE on $(TARGET) = $(BIN_DIR)$(OBJ_SUBDIR) ;
   depends $(TARGET) : $(SOURCE) $(BIN_DIR)$(OBJ_SUBDIR) ;
   temporary $(TARGET) ;
   
   HDRSCAN on $(SOURCE) = $(HDRPATTERN) ;
   
   CreateDirectory $(BIN_DIR)$(OBJ_SUBDIR) ;

   CCOPTS on $(TARGET) += $(LOC_CCOPTS) ;
   
   if ( $(OBJ_SUBDIR) == static )
   {
      if ( $(SOURCE:S) == ".c" )
        CompileStaticObject_C   $(TARGET) : $(SOURCE) ;
      else
        CompileStaticObject_CXX $(TARGET) : $(SOURCE) ;
   }

   if ( $(OBJ_SUBDIR) == shared )
   {
      if ( $(SOURCE:S) == ".c" )
         CompileSharedObject_C   $(TARGET) : $(SOURCE) ;
      else
         CompileSharedObject_CXX $(TARGET) : $(SOURCE) ;
   }

   Clean clean : $(TARGET) ;
   
   return $(TARGET) ;
}

rule SharedObject TARGET : SOURCE : LOC_CCOPTS
{
   Object $(TARGET) : $(SOURCE) : shared : $(LOC_CCOPTS) ;
}

rule StaticObject TARGET : SOURCE : LOC_CCOPTS
{
   Object $(TARGET) : $(SOURCE) : static : $(LOC_CCOPTS) ;
}

rule ObjectSet  TARGET : SOURCES : OBJ_SUBDIR
{
   if ( $(PLATFORM) != win32 ) OBJ_SUBDIR = static ;
   
   HDRSCAN on $(SOURCES) = $(HDRPATTERN) ;

   local Y_SOURCES   = $(SOURCES:I="\.y$") ;
   local L_SOURCES   = $(SOURCES:I="\.l$") ;
   local FSM_SOURCES = $(SOURCES:I="\.fsm$") ;
   local C_SOURCES   = $(SOURCES:I="\.c$") ;
   local CXX_SOURCES = $(SOURCES:I="\.cpp$") $(FSM_SOURCES:S=.cpp) ;

   local C_OBJECTS ;
   local CXX_OBJECTS ;
            
   if ( $(PARSEGEN_C) )
      C_SOURCES   += $(Y_SOURCES:S=_YY.c) $(L_SOURCES:S=_ll.c) ;
   else
      CXX_SOURCES += $(Y_SOURCES:S=_YY.cpp) $(L_SOURCES:S=_ll.cpp) ;
   
   for ( SRC_FILE in $(C_SOURCES) )
   {
      C_OBJECTS += <$(OBJ_SUBDIR)>$(SRC_FILE:S="$(OBJ_SUFFIX)") ;
      depends <$(OBJ_SUBDIR)>$(SRC_FILE:S="$(OBJ_SUFFIX)") : $(SRC_FILE) ;
   }
   
   for ( SRC_FILE in $(CXX_SOURCES) )
   {
      CXX_OBJECTS += <$(OBJ_SUBDIR)>$(SRC_FILE:S="$(OBJ_SUFFIX)") ;
      depends <$(OBJ_SUBDIR)>$(SRC_FILE:S="$(OBJ_SUFFIX)") : $(SRC_FILE) ;
   }

   if ( $(PARSEGEN_C) )
   {
      for ( Y_SRC in $(Y_SOURCES) )
      {
         C_OBJECTS += <$(OBJ_SUBDIR)>$(Y_SRC:S="_YY$(OBJ_SUFFIX)") ;
         YaccRule $(Y_SRC:S=_YY.c) : $(Y_SRC) ;
      }
     
      for ( L_SRC in $(L_SOURCES) )
      {
         C_OBJECTS += <$(OBJ_SUBDIR)>$(L_SRC:S="_ll$(OBJ_SUFFIX)") ;
         LexRule $(L_SRC:S=_ll.c) : $(L_SRC) ;
      }
      
      for ( FSM_SRC in $(FSM_SOURCES) )
      {
         C_OBJECTS += <$(OBJ_SUBDIR)>$(FSM_SRC:S="$(OBJ_SUFFIX)") ;
         FsmRule $(FSM_SRC:S=.c) : $(FSM_SRC) : $(FSM_TEMPLATE_FILE:E=fsmc.tpl) : $(FSM_ID_FILE:E=id.fsm) ;
      }
      
   } else {
   
      for ( Y_SRC in $(Y_SOURCES) )
      {
         CXX_OBJECTS += <$(OBJ_SUBDIR)>$(Y_SRC:S="_YY$(OBJ_SUFFIX)") ;
         YaccRule $(Y_SRC:S=_YY.cpp) : $(Y_SRC) ;
      }
     
      for ( L_SRC in $(L_SOURCES) )
      {
         CXX_OBJECTS += <$(OBJ_SUBDIR)>$(L_SRC:S="_ll$(OBJ_SUFFIX)") ;
         LexRule $(L_SRC:S=_ll.cpp) : $(L_SRC) ;
      }
      
      for ( FSM_SRC in $(FSM_SOURCES) )
      {
         CXX_OBJECTS += <$(OBJ_SUBDIR)>$(FSM_SRC:S="$(OBJ_SUFFIX)") ;
         FsmRule $(FSM_SRC:S=.cpp) : $(FSM_SRC) : $(FSM_TEMPLATE_FILE:E=fsmc.tpl) : $(FSM_ID_FILE:E=id.fsm) ;
      }
   }

   # if the output directory does not exist it must be created   
   LOCATE on $(BIN_DIR)$(OBJ_SUBDIR) = . ;
   depends $(CXX_OBJECTS) $(C_OBJECTS) : $(BIN_DIR)$(OBJ_SUBDIR) ;
   CreateDirectory $(BIN_DIR)$(OBJ_SUBDIR) ;

   LOCATE on $(CXX_OBJECTS) $(C_OBJECTS) = $(BIN_DIR)$(OBJ_SUBDIR) ;
   
   depends $(TARGET) : $(CXX_OBJECTS) $(C_OBJECTS) ;
   temporary $(CXX_OBJECTS) $(C_OBJECTS) ;

   if ( $(OBJ_SUBDIR) == static )
   {
      if ( $(CXX_SOURCES) ) { CompileStaticObjectList_CXX $(CXX_OBJECTS) : $(CXX_SOURCES) ; }
      if ( $(C_SOURCES)   ) { CompileStaticObjectList_C   $(C_OBJECTS)   : $(C_SOURCES)   ; }
   }

   if ( $(OBJ_SUBDIR) == shared )
   {
      if ( $(CXX_SOURCES) ) { CompileSharedObjectList_CXX $(CXX_OBJECTS) : $(CXX_SOURCES) ; }
      if ( $(C_SOURCES)   ) { CompileSharedObjectList_C   $(C_OBJECTS)   : $(C_SOURCES)   ; }
   }

   Clean clean : $(CXX_OBJECTS) $(C_OBJECTS) ;
   
   return $(CXX_OBJECTS) $(C_OBJECTS) ;
}

rule YaccRule C_SOURCE : Y_SOURCE
{
   depends $(Y_SOURCE:S=_YY.cpp) $(Y_SOURCE:S=_YY.hpp) : $(Y_SOURCE) ;
   LOCATE on $(Y_SOURCE:S=_YY.cpp) $(Y_SOURCE:S=_YY.hpp) = $(BIN_DIR) ;
   ProcessYacc $(Y_SOURCE:S=_YY.cpp) $(Y_SOURCE:S=_YY.hpp) : $(Y_SOURCE) ;
   Clean clean : $(Y_SOURCE:S=_YY.cpp) $(Y_SOURCE:S=_YY.hpp) ;
}

rule LexRule C_SOURCE : L_SOURCE
{
   depends  $(L_SOURCE:S=_ll.cpp) : $(L_SOURCE) $(L_SOURCE:S=_YY.hpp) ;
   includes $(L_SOURCE:S=_ll.cpp) : $(L_SOURCE:S=_YY.hpp) ;
   LOCATE on $(L_SOURCE:S=_ll.cpp) $(L_SOURCE:S=_ll.hpp) = $(BIN_DIR) ;
   ProcessLex $(L_SOURCE:S=_ll.cpp) : $(L_SOURCE) ;
   Clean clean : $(L_SOURCE:S=_ll.cpp) ;
}

rule FsmIdHeader TARGETS : SOURCES
{
   InitDirs ;
   
   FSM_ID_FILE ?= id.fsm ;
   LOCATE on $(FSM_ID_FILE) = $(BIN_DIR) ;
   
   notfile $(FSM_ID_FILE) ;
   depends $(TARGETS) : $(FSM_ID_FILE) $(FSM_TEMPLATE_FILE:E=fsm.tpl) $(SOURCES:S=.cpp) ;
   LOCATE on $(TARGETS) = $(BIN_DIR) ;
   ProcessFsmIdHeader $(TARGETS) : $(FSM_TEMPLATE_FILE:E=fsm.tpl) : $(FSM_ID_FILE) ;
   Clean clean : $(TARGETS) ;
}

rule FsmRule C_SOURCE : FSM_SOURCE
{
   FSM_ID_FILE ?= id.fsm ;
   LOCATE on $(FSM_ID_FILE) = $(BIN_DIR) ;
   
   depends  $(C_SOURCE:S=.cpp) $(C_SOURCE:S=.h) : $(FSM_SOURCE) $(FSM_TEMPLATE_FILE:E=fsm.tpl) ;
   depends  $(FSM_ID_FILE) : $(C_SOURCE:S=.cpp) $(C_SOURCE:S=.h) ;
   includes $(C_SOURCE:S=.cpp) : $(C_SOURCE:S=.h) ;
   LOCATE on $(C_SOURCE:S=.cpp) $(C_SOURCE:S=.h) = $(BIN_DIR) ;
   ProcessFsm $(C_SOURCE:S=.cpp) $(C_SOURCE:S=.h) : $(FSM_SOURCE) : $(FSM_TEMPLATE_FILE:E=fsm.tpl) : $(FSM_ID_FILE) ;
   Clean clean : $(C_SOURCE:S=.cpp) $(C_SOURCE:S=.h) $(FSM_ID_FILE) ;
}

rule HeaderRule INCLUDER : INCLUDEDS
{
   includes $(INCLUDER) : $(INCLUDEDS) ;
   HDRSCAN on $(INCLUDEDS) = $(HDRPATTERN) ;  # recursively search headers
   
   # Normally in build systems we want this. It means that if a header is not found, that its ok.
   nocare $(INCLUDEDS) ;                      
}

rule CleanTarget TARGET : TARGET_DIR
{
   local LIST = $(TARGET) ;                                                                                      # all the targets
   
   LIST += $(TARGET:HS=.pdb) $(TARGET:HS=.exp) $(TARGET:HS=.ilk) $(TARGET:H).manifest ;                          # clean associated compiler generated file
   LIST += $(TARGET:HS=.suo) $(TARGET:HS=.sln) ;                                                                 # clean msvc ide generated files
   LIST += $(TARGET:HN=".exe"0="_pure.log") $(TARGET:HN=".exe"0="_pure.ini")  $(TARGET:HN=".exe"0="_exe.pft") ;  # clean purify generated files
           
   LOCATE on $(LIST) = $(TARGET_DIR) ;
   Clean clean : $(LIST) ;
}

rule ExternalDlls TARGET : DLLS : TARGET_DIR
{
   if ( !$(TARGET_DIR) ) 
   {
      TARGET_DIR = $(BIN_DIR) ;
      depends $(TARGET) : $(TARGET_DIR) ;
      CreateDirectory $(TARGET_DIR) ;
   }
   
   for ( DLL in $(DLLS) )
   {
      REMOTE_DLL = <remote>$(DLL) ;
      LOCATE on $(DLL) = $(TARGET_DIR) ;
      SEARCH on $(DLL) = $(TARGET_DIR) ;
      
      # look for remote file in the lib dirs, unless they include the local dir
      SEARCH on $(REMOTE_DLL) = $(LIB_DIRS:X="^$(TARGET_DIR)$") ;
   
      depends $(TARGET) : $(DLL) ;
      depends $(DLL) : $(REMOTE_DLL) ;
      CopyFile $(DLL) : $(REMOTE_DLL) ;
      Clean clean : $(DLL) ;
   }
}
 
rule ConcatDocument TARGET : SOURCES : DIR
{
   SEARCH on $(SOURCES) = $(DIR) ;
   LOCATE on $(TARGET) = $(DIR) ;
   depends $(TARGET) : $(SOURCES) ;
   ConcatDocumentAction $(TARGET) : $(SOURCES) ;
}

rule CreateDirectory TARGET
{
   noupdate $(TARGET) ;
   CreateDirectoryAction $(TARGET) ;
}

rule SubProject TARGET : DEPENDENTS : PROJTARGET
{
   InitDirs ;
   
   notfile $(TARGET) ;
   always  $(TARGET) ;
   depends all : $(TARGET) ;
   depends $(TARGET) : $(DEPENDENTS) ;
   CleanSubProject clean : $(TARGET) ;
   
   if ( $(PROJTARGET) )
   {
      for ( T in $(PROJTARGET) )
         BuildSubProject $(TARGET) : $(T) ;
   } else {
      BuildSubProject $(TARGET) : $(PROJTARGET:E=all) ;
   }
}

#----- cross platform actions ---------------------------------------------------

action quietly BuildSubProject TARGET : PROJTARGET
{%
   echo Building $(TARGET:B) $(PROJTARGET:X=all) --------------------
   $(JAMNAME) $(JAMCMDOPTIONS:X=-c) -c $(TARGET:B) -h 1 -s CURFLAV=$(CURFLAV) -s COLUMNS=$(COLUMNS) $(PROJTARGET)
%}

action quietly piecemeal 1 CleanSubProject SOURCE : TARGET
{%
   echo Cleaning $(TARGET:B) ---------------------------------
   $(JAMNAME) $(JAMCMDOPTIONS:X=-c) -c $(TARGET:B) -h 1 -s CURFLAV=$(CURFLAV) -s COLUMNS=$(COLUMNS) clean
%}

action quietly CreateDirectoryAction TARGET
{%
   echo Making Directory     $(TARGET)
   mkdir $(TARGET)
%}

action together piecemeal existing quietly Clean TARGETS : SOURCES
{% 
   echo Cleaning             $(SOURCES)
   rm -f $(SOURCES:C)
%}

action quietly ProcessYacc TARGET : SOURCE
{%
   echo Yacc                 $(TARGET:H) : $(SOURCE:H)
   $(YACC) $(YACC_FLAGS) -d -o$(TARGET[0]) -p$(SOURCE:BU) $(SOURCE)
%}

action quietly ProcessLex TARGET : SOURCE
{%
   echo Lex                  $(TARGET:H) : $(SOURCE:H)
   $(LEX) -o$(TARGET) $(SOURCE)
%}

action quietly ProcessFsm TARGET : SOURCES : TEMPLATE_FILE : ID_FILE on fsmc
{%
   echo Fsm                  $(TARGET:H) : $(SOURCES:H)
   $(FSMC) -t$(TEMPLATE_FILE:F) -i$(ID_FILE:F) -o$(TARGET[0]:D)$(TARGET[0]:B) $(SOURCES)
%}

action quietly ProcessFsmIdHeader TARGET : TEMPLATE_FILE : ID_FILE on fsmc
{%
   echo Fsm Id File          $(TARGET:H) : $(ID_FILE:H)
   $(FSMC) -a$(TARGET[0]:D)$(TARGET[0]:B) -t$(TEMPLATE_FILE) -i$(ID_FILE:F)
%}

action quietly ConcatDocumentAction TARGET : SOURCES
{%
   echo Contatenating        $(TARGET) : $(SOURCES)
   cat $(SOURCES) | rgxrpl -x docserv.php/page/doc_ref\# -0 \# > $(TARGET)
%}

action quietly CopyFile TARGET : SOURCE
{%
   echo Copying              $(TARGET:H) : $(SOURCE)
   cp $(SOURCE) $(TARGET)
%}

