# p4/Jamrules
#
# This Jamrules describes how to build most of Perforce, exclusive of
# windows only products.
#
# This file is organized into sections:
#
#	Section 1.  Global variable settings.
#	Section 2.  Library names.
#	Section 3.  Per-build type variable settings.
#	Section 4.  Per-platform variable settings.
#	Section 5.  Perforce-special rules and actions.
# 	Section 6.  Perforce-special Windows rules.
#	Section 7.  QT build rules and actions.
#	Section 8.  Lua build rules and actions.
#	Section 9.  Per-platform actions.
#

#################################################
#
# Section 1.  Global variable settings.
#
#################################################

	if $(JAMBASEDATE) < 2002.05.09 {
	    Exit Jamrules requires Jambase 2002.05.09 ($(JAMBASEDATE)) ;
	}

	# Variables you shouldn't set:
	#
	#   OS - operating system ("FreeBSD")
	#   OSPLAT - OS platform ("sparc")
	#
	# Variables you can set:
	#
	#   OSVER - version of OS ("102" for MACOSX)
	#   TYPE - controls compile flags (see below)
	#   BUILD - subdirectory for special named builds ("nightly")

        # For convenience of historical compatibility, the OSPLAT value
        # "AMD64" will be changed to "X86_64", which is the canonical name
        # we are now using for that platform.  Please get into the habit of
        # using it directly, as this may go away someday.
        if $(OSPLAT) = AMD64 { OSPLAT = X86_64 ; }

	# This is jam idiomatic, but the result is that
	# P4BIN is set to ../p4-bin (relative to P4)

	SubDir AllP4 p4 ;	# where we are
	SubDir AllP4 p4-bin ;	# where we want to be
	SubDir P4BIN ;		# name is that
	SubDir AllP4 p4 ;	# back to where we started

	EXEC_LIB_TOKENS =
		P4BIN
		lib.$(OS:L)$(OSVER:EL)$(OSPLAT:EL)
		;
	EXEC_LIB ?= [ FSubDirPath $(EXEC_LIB_TOKENS) ] ;

	EXEC_LIBEXEC_TOKENS =
		P4BIN
		libexec.$(OS:L)$(OSVER:EL)$(OSPLAT:EL)
		;
	EXEC_LIBEXEC ?= [ FSubDirPath $(EXEC_LIBEXEC_TOKENS) ] ;

	# Build dir: p4-bin/bin.xxx[/build][/type]
	EXEC_TOKENS =
		P4BIN
		bin.$(OS:L)$(OSVER:EL)$(OSPLAT:EL)
		$(BUILD)
		$(TYPE:L)
		;

	EXEC ?= [ FSubDirPath $(EXEC_TOKENS) ] ;
	ALL_LOCATE_TARGET = $(EXEC) ;

	# version file
	# Ident'ed executables depend on this

	SEARCH on Version Jamrules = $(P4) ;
	include Version ;

	STRIP    = strip ;
	COMPRESS = gzip -9 ;

	# symbolic flags with no user/group/other specifier will default to
	# ANDing with the user's umask.
	# Thus, if the user's umask is 022,
	#  files will be -rw-r--r-- and executables will be -rwxr-xr-x
	# If a user's umask is 002,
	#  files will be -rw-rw-r-- and executables will be -rwxrwxr-x
	# and so on.

	if $(UNIX)
	{
		FILEMODE = "+r,go-w" ;
		EXEMODE  = "+rx,go-w" ;
	}

        # can be overridden on jam cmdline with -sSMARTHEAP=no
        # Smartheap is currently only used on NT and Linux.
        SMARTHEAP ?= yes ;

	DEFINES +=
		OS_$(OS)
		OS_$(OS)$(OSVER)
		OS_$(OS)$(OSPLAT)
		OS_$(OS)$(OSVER)$(OSPLAT) ;

	HDRS +=
		[ FSubDirPath P4 msgs ]
		[ FSubDirPath P4 support ]
		[ FSubDirPath P4 sys ] ;

#################################################
#
# Section 2.  Library names.
#
#################################################

	rule SetLibName
	{
		$(1) = $(2:S=$(SUFLIB)) ;
		LOCATE on $($(1)) = $(EXEC) ;
	}

	SetLibName CLIENTLIB        : libclient     ;
	SetLibName DMLIB            : libdm         ;
	SetLibName FTPLIB 	    : libp4ftp 	    ;
	SetLibName LBRLIB           : liblbr        ;
	SetLibName P4EXPLIB         : libp4exp      ;
	SetLibName P4TD             : libp4thumb    ;
	SetLibName P4LIB            : libp4         ;
	SetLibName P4SCCLIB         : libp4scc      ;
	SetLibName P4WINLIB         : libp4win      ;
	SetLibName P4WINCMNLIB      : libp4wcmn     ;
	SetLibName P4WINDIFFLIB     : libp4wdf      ;
	SetLibName P4WINMRGLIB      : libp4wmrg     ;
	SetLibName PLUGINLIB 	    : libplugin     ;
	SetLibName PROXYLIB	    : libproxy      ;
	SetLibName QTCMDLIB         : libqtcmd      ;
	SetLibName QTCORELIB        : libqtcore     ;
	SetLibName QTP4APILIB       : libqtp4api    ;
	SetLibName QTIMAGELIB       : libqtimage    ;
	SetLibName QTIMGMAXLIB      : libqtmaxfmt   ;
	SetLibName QTIMGMAYALIB     : libqtmayafmt  ;
	SetLibName QTIMGPHOTOLIB    : libqtphotofmt ;
	SetLibName QTIMGTGALIB      : libqttgafmt   ;
	SetLibName QTMERGELIB       : libqtmerge    ;
	SetLibName QTMERGEAPPLIB    : libqtmergeapp ;
	SetLibName QTPLATLIB        : libqtplat     ;
	SetLibName QTPREFLIB        : libqtpref     ;
	SetLibName QTUTILLIB        : libqtutil     ;
	SetLibName QTREELIB         : libqtree      ;
	SetLibName QTZEROCONFLIB    : libqtzeroconf ;
	SetLibName RPCLIB           : librpc        ;
	SetLibName SANDSTORM        : libstorm      ;
	SetLibName P4ALIB           : libp4a        ;
	SetLibName P4V              : libp4v        ;
	SetLibName P4VTEST          : libp4vtest    ;
	SetLibName SCCDLLLIB        : p4scc2        ;
	SetLibName SERVERLIB        : libserver     ;
	SetLibName SUPPORTLIB       : libsupp       ;
	SetLibName WEBGIZMOLIB	    : libp4web      ;
	SetLibName ZEROCONFLIB	    : libzeroconf   ;

#################################################
#
# Section 3.  Per-build type variable settings.
#
#################################################

	TYPE ?= opt ;

	switch $(TYPE)
	{
	# These are official builds
	#
	#  dyn: windows guis must be dynamic
	#  opt: our standard, optimized built
	#  pic: for special customer requests

	case dyn :	OPTIM = -O2 ;
	case opt : 	OPTIM = -O2 ;
	case pic : 	OPTIM = -O2 -fPIC ;

	# These are for internal testing/playing
	#
	#  g/dyng/optg: debugging
	#  pg: profiled executable on unix
	#  fast: a fast compile (no optimization)
	#  lower: case insensitive on UNIX
	#  lpg: lower profiled

	case g : 	OPTIM = -g ;
	case dyng :	OPTIM = -g ;
	case fast :	OPTIM = ;
	case lower :	OPTIM = -DCASE_INSENSITIVE -O2 ;
	case lpg :	OPTIM = -DCASE_INSENSITIVE -O2 -pg ; LINKFLAGS = -pg ;
	case optg : 	OPTIM = -O2 -g ;
	case pg : 	OPTIM = -pg -O ; LINKFLAGS = -pg ;
	case sym :	OPTIM = -opt off -sym full ; LINKFLAGS = -sym full ;

	case *vsdebug : # special-target builds; see NT section

	case * : 	Echo "Warning -- unknown compilation TYPE" $(TYPE) ;
	}

	# TYPE_DEBUG for all debug builds.
	# TYPE_DYNAMIC for all dynamic builds.

	switch $(TYPE) { case *g :	TYPE_DEBUG = true ; }
	switch $(TYPE) { case dyn* :	TYPE_DYNAMIC = true ; }

	# Some things don't get built dynamically/statically.

	if ! $(TYPE_DYNAMIC) || $(OS) != NT { BUILD_P4D = true ; }

#################################################
#
# Section 4.  Per-platform variable settings.
#
#################################################

	# Flags for Perforce
	#
	#	CASE_INSENSITIVE -- case folding server
	#	ENUM_INT -- force enums to int sized for watcom
	#	USE_CRLF -- ascii opened as binary needs special handling
	#	USE_CR -- special CR <-> LF translation for mac
	#	USE_EBCDIC -- ascii <-> ebcdic translation in rpc

	GENFLAGS = CCFLAGS C++FLAGS ;

	switch $(OS)$(OSVER) $(OS)
	{
	case AIX53 :
		C++ = g++ ;
		CC  = gcc ;
		LINK = gcc ;

		C++FLAGS += -DBSD -Dunix -D_LARGE_FILES=1 ;
		LINKLIBS += -lsupc++ ;

		switch $(OSPLAT)
		{
		case PPC64 :
			$(GENFLAGS) += -maix64 ;
			LINKFLAGS   += -maix64 ;
			AR           = ar -X 64 -ru ;
			STRIP        = strip -X 64 ;
		}

	case CYGWIN :
	    STRIP = ;
	    CC = gcc ;
	    C++ = gcc ;
	    LINK = g++ ;
	    C++FLAGS += -DUSE_CRLF ;

	case DARWIN :
	    CC = cc ;
	    C++ = cc ;
	    C++FLAGS += -DCASE_INSENSITIVE ;

	case DARWIN60cs : #case-sensitive
	    CC = cc ;
	    C++ = cc ;
            LINK = g++ ;

	case DARWIN8* :
	   CC	= gcc ;
	   C++	= g++ ;
	   LINK = g++ ;

	   MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk ;
	   LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ;

		switch $(OSVER:U)
		{
             case *CS :
             case *   : C++FLAGS += -DCASE_INSENSITIVE ;
           }

		switch $(OSPLAT)
		{
	     case X86 :    _arch = i386   ;
	     case X86_64 : _arch = x86_64 ;
	     case *   :    _arch = ppc    ;
	   }

	   $(GENFLAGS) += -arch $(_arch) -DOS_DARWIN80 ;
	   LINKFLAGS   += -arch $(_arch) ;

	case DARWIN9* :
		CC   = gcc ;
		C++  = g++ ;
		LINK = g++ ;

		MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ;
		LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ;

		switch $(OSVER:U)
		{
		case *CS :
		case *   : C++FLAGS += -DCASE_INSENSITIVE ;
		}

		switch $(OSPLAT)
		{
		case X86 :    _arch = i386   ;
		case X86_64 : _arch = x86_64 ;
		case *   :    _arch = ppc    ;
		}

		$(GENFLAGS) += -arch $(_arch) -DOS_DARWIN90 ;
		LINKFLAGS   += -arch $(_arch) ;

	case FREEBSD :
	    Exit Set OSVER to 4, 5, or 6 for FreeBSD ;

	case FREEBSD4 :
		CC   = gcc ;
		C++  = g++ ;
		LINK = gcc ;

		switch $(OSCOMP)
		{
		case GCC3 : LINKLIBS += -lsupc++ ;
		}

		if $(OSPLAT) != AXP { LINKFLAGS += -static ; }
		$(GENFLAGS) += -pipe ;

	case FREEBSD[56789]* :
		CC   = gcc ;
		C++  = g++ ;
		LINK = gcc ;
		# supc++ library on freebsd5.x and later is missing some
		# modules (this is a bug), so we can't use it.
		# But we still do not want to link stdc++ dynamically.
		#LINKLIBS += -lsupc++ ;
		LINKLIBS += -Wl,-dn,-lstdc++,-dy ;

		_mflags = ;
		switch $(OSPLAT)
		{
		case X86    : _mflags = -m32 ;
		case X86_64 : _mflags = -m64 ;
		}

		$(GENFLAGS) += $(_mflags) -pipe ;
		LINKFLAGS   += $(_mflags) ;

		QTOPENGL ?= no ;

	case HPUX11 :
		switch $(OSPLAT:E)-$(OSCOMP:E)
		{
		# On IA64, hpux supports both 64-bit and 32-bit executables.
		# We build 64-bit for the benefit of p4d, and client apps are built
		# the same way for the sake of simplicity.
		case IA64-GCC :
			CC           = gcc ;
			C++          = gcc ;
			$(GENFLAGS) += -mlp64 ;

			LINK         = gcc ;
			LINKFLAGS   += -mlp64 ;
			LINKLIBS    += -lsupc++ -lunwind ;

		case IA64-* : # unbundled vendor compiler
			CC           = aCC ;
			C++          = aCC ;
			OPTIM        = +O1 ;
			if $(TYPE) = pic { OPTIM += +Z ; }

			$(GENFLAGS) += +DD64 +noeh -z ;

			# Suppress compiler warnings:
 			# 	2611: overloaded virtual function "x" is only partially overridden in class "y"
 			# 	2997: function "x::fn is hidden by y::fn" -- virtual function override intended?
			$(GENFLAGS) += +W2611,2997 ;

			LINK         = aCC ;
			# The +hideallsymbols linker option will generate a
			# lot of harmless warnings about being unable to hide
			# symbols that are undefined and need resolving
			# from the (dynamically linked) system libraries,
			# but see //depot/main/p4-doc/code/PORTING for rationale.
			LINKFLAGS   += +DD64 +Oprocelim -z -Wl,+hideallsymbols,+stripunwind ;

		case PA11-* : # unbundled vendor compiler
			CC    = aCC ;
			C++   = aCC ;
			LINK  = aCC ;
			OPTIM = +O1 ;
			$(GENFLAGS) += -D_LARGEFILE64_SOURCE +DA1.1 ;

		case *-* : # assumed PA20 (32-bit) with unbundled vendor compiler
			CC           = aCC ;
			C++          = aCC ;
			LINK         = aCC ;
			OPTIM        = +O1 ;
			$(GENFLAGS) += -D_LARGEFILE64_SOURCE ;
	    }

	case IRIX65 :
		CC   = cc -OPT:Olimit 5000 -64 -mips3 ;
		C++  = CC -woff 3439,1174,1178,1681,1682
		          -OPT:Olimit 5000 -64 -mips3 ;
		LINK = CC -64 ;

		if $(TYPE) = pic
		{
			OPTIM = -O2 -KPIC ;
		}

	case LINUX :
		Exit Set OSVER to 24 or 26 ;

	case LINUX2[46] :
		CC   = gcc ;
		C++  = g++ ;
		LINK = gcc ;
		LINKLIBS += -lsupc++ # Assumes gcc 3.x or later
		            -ldl ;   # for zeroconf

		# be explicit about submodel since we may be compiling x86 code on
		# an x86/x86_64 biarch system, and the default may be uncertain.
		_mflags = ;
		switch $(OSPLAT)
		{
		case X86    : _mflags = -m32 ;
		case X86_64 : _mflags = -m64 ;
		}

		if $(SMARTHEAP) = yes { $(GENFLAGS) += -DUSE_SMARTHEAP ; }

		$(GENFLAGS) += $(_mflags) -D_GNU_SOURCE ;
		LINKFLAGS   += $(_mflags) ;

		QTOPENGL ?= no ;

	case MACOSX :
	    CC = cc ;
	    C++ = cc ;
	    $(GENFLAGS) += -DCASE_INSENSITIVE ;
  	    $(GENFLAGS) += -fpascal-strings ;
	    # This looks like a flag but it is really a library macro
	    # kind of thing and causes link problems if it at the front
	    # of the link command so we make it a LIB
  	    LINKLIBS += -framework Carbon ;

	case MACOSX104 :  # assumes using gcc 4.0.1 or newer
		CC   = gcc ;
		C++  = g++ ;
		LINK = g++ ;

		MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk ;

		# The -fvisibility-inlines-hidden option is a C++-only
		# option, needed because Qt4 is built with it and all
		# statically-compiled objects need to use it consistently.
		C++FLAGS    += -fvisibility-inlines-hidden ;
		$(GENFLAGS) += -DCASE_INSENSITIVE
		               -fpascal-strings
		               -isysroot$(MACOSX_SDK) ;
		LINKFLAGS   += -Wl,-syslibroot,$(MACOSX_SDK) ;
		# This looks like a flag but it is really a library macro
		# and causes link problems if it's at the front of the link
		# command, so we make it a LIB.
		LINKLIBS    += -framework Carbon ;

		switch $(OSPLAT)
		{
		# Note: we may elect at some point to generate universal
		# binaries, in which case just add multiple -arch [arch]
		# flags here.
		#case X86   : _arch = -arch i386 -arch ppc ;
		case X86    : _arch = -arch i386   ;
		case X86_64 : _arch = -arch x86_64 ;
		case *      : _arch = -arch ppc    ;
		}

		$(GENFLAGS) += $(_arch) -DCASE_INSENSITIVE ;
		LINKFLAGS   += $(_arch) ;

		# This adds $(QTDIR)/lib as a frameworks directory, in case
		# Qt is built as frameworks.  On the mac, it can be built
		# either as frameworks, regular unix-style shared
		# libraries, or unix-style static libaries.
		$(GENFLAGS)  += -F$(QTDIR)/lib ;

	case MACOSX105 :  # assumes using gcc 4.0.1 or newer
		CC   = gcc ;
		C++  = g++ ;
		LINK = g++ ;

		MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ;

		# The -fvisibility-inlines-hidden option is a C++-only
		# option, needed because Qt4 is built with it and all
		# statically-compiled objects need to use it consistently.
		C++FLAGS    += -fvisibility-inlines-hidden ;
		$(GENFLAGS) += -DCASE_INSENSITIVE
		               -fpascal-strings
		               -isysroot$(MACOSX_SDK) ;
		LINKFLAGS   += -Wl,-syslibroot,$(MACOSX_SDK) ;
		# This looks like a flag but it is really a library macro
		# and causes link problems if it's at the front of the link
		# command, so we make it a LIB.
		LINKLIBS    += -framework Carbon ;

		switch $(OSPLAT)
		{
		# Note: we may elect at some point to generate universal
		# binaries, in which case just add multiple -arch [arch]
		# flags here.
		#case X86   : _arch = -arch i386 -arch ppc ;
		case X86    : _arch = -arch i386   ;
		case X86_64 : _arch = -arch x86_64 ;
		case *      : _arch = -arch ppc    ;
		}

		$(GENFLAGS) += $(_arch) -DCASE_INSENSITIVE ;
		LINKFLAGS   += $(_arch) ;

		# This adds $(QTDIR)/lib as a frameworks directory, in case
		# Qt is built as frameworks.  On the mac, it can be built
		# either as frameworks, regular unix-style shared
		# libraries, or unix-style static libaries.
		$(GENFLAGS)  += -F$(QTDIR)/lib ;

	case NETBSD* :
	    CC = /usr/pkg/gcc34/bin/gcc ;
	    C++ = /usr/pkg/gcc34/bin/g++ ;
	    $(GENFLAGS) += -pipe -Dunix ;
	    LINK = /usr/pkg/gcc34/bin/g++ ;
	    # NetBSD gcc choked on -O2 -fPIC
	    if $(TYPE) = pic { OPTIM = -O1 -fPIC ; }

	case VMS* :
	    # use C++ compiler: we're cheap
	    CC = cxx ;
	    C++ = cxx ;
	    DEFINES += NO_MEMCPY ;
	    STRIP = ;
	    OPTIM = ;

	case NT* :
	    # Use setargv.obj to get wildcard expansion.
	    # The "rc" tool needs MS headers:

	    BINDIR = e:\\perforce ;
	    JAMSHELL ?= $(P4)\\Jamsh.bat $(OSPLAT) % "!" ;

	    C++FLAGS += /DCASE_INSENSITIVE /DUSE_CRLF /wd4996 ;
	    if $(SMARTHEAP) = yes { $(GENFLAGS) += /DUSE_SMARTHEAP ; }

	    LINKLIBS = setargv.obj advapi32.lib oldnames.lib
		           kernel32.lib ws2_32.lib ;

		if $(OSPLAT) = IA64
		{
			# When using the windows 2003 SDK on IA64, the /GS flag is
			# enabled by default but even if you disable it for our own
			# builds, the libraries provided with the SDK itself were build
			# with /GS, so there's no way to avoid having to link against
			# this library.
			#
			# See http://support.microsoft.com/?id=894573
			LINKLIBS += bufferoverflowU.lib ;
		}


	    STDHDRS = $(MSVCNT)\\include $(MSVCNT)\\atlmfc\\include ;
	    STRIP = ;

	    # Now, unset STDHDRS so Jam doesn't scan system headers (takes
	    # too long when using compiler on networked machine):

	    STDHDRS = ;

	    if $(BCCROOT)
	    {
		# Jeff Anton compiles with borland.

		OPTIM = -O2 ;
		RCFLAGS = /d NDEBUG /r ;
		AR = tlib /C /P128 ;
		LINKLIBS = $(BCCROOT)/lib/wildargs.obj ;
	    }
	    else if $(TYPE) = g
	    {
		# Debugging build

		OPTIM = /Zi /Gm ;
		RCFLAGS = /d DEBUG /r ;
		LINKFLAGS += /DEBUG ;
		$(GENFLAGS) += /MTd ;
		}
	    else if $(TYPE) = dyn
	    {
		# Dynamic link version, for qt products

		if $(JAMFAST)
		{
			OPTIM = /Z7 /O2 ;
		}
		else
		{
			OPTIM = /Zi /O2 ;
			actions Cc
			{
			$(CC) /c /Fo$(<) /Fd$(EXEC)\ $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I"$(STDHDRS)" $(>)
			}
			actions C++
			{
			$(C++) /c /Fo$(<) /Fd$(EXEC)\ $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I"$(STDHDRS)" /Tp$(>)
			}
		}
		RCFLAGS = /d NDEBUG /r ;
		$(GENFLAGS) += /MD ;

		LINKFLAGS += /MAP /OPT:REF /OPT:ICF /DEBUG ;
	    }
	    else if $(TYPE) = dyng
	    {
		# Dynamic Debugging build
		if $(JAMFAST)
		{
			OPTIM = /Z7 ;
		}
		else
		{
			OPTIM = /Zi /Gm ;
			actions Cc
			{
			$(CC) /c /Fo$(<) /Fd$(EXEC)\ $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I"$(STDHDRS)" $(>)
			}
			actions C++
			{
			$(C++) /c /Fo$(<) /Fd$(EXEC)\ $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I"$(STDHDRS)" /Tp$(>)
			}
		}
		RCFLAGS = /d DEBUG /r ;
		$(GENFLAGS) += /MDd ;
		LINKFLAGS += /DEBUG /NODEFAULTLIB:msvcrt.lib  /fixed:no ;
	    }
	    else if $(TYPE) = vsdebug
	    {
		# Static link with Visual Studio debug libraries.
		# This does not enable debugging our own code, just sets
		# linker dependencies for VS libraries.
		# This is intended for customer use.

		OPTIM        = /O2 ;
		RCFLAGS      = /d NDEBUG /r ;
		$(GENFLAGS) += /MTd ;
		LINKFLAGS   += /MAP ;
	    }
	    else if $(TYPE) = dyn_vsdebug
	    {
		# Dynamic link with Visual Studio debug libraries.
		# This does not enable debugging our own code, just sets
		# linker dependencies for VS libraries.
		# This is intended for customer use.

		OPTIM        = /O2 ;
		RCFLAGS      = /d NDEBUG /r ;
		$(GENFLAGS) += /MDd ;
		LINKFLAGS   += /MAP /OPT:REF /OPT:ICF ;
	    }
	    else if $(OSVER) = 98
	    {
		# Dynamic link version for win98 version of p4win
		# Goes into bin.win98 -- oddity.

		EXEC = [ FSubDirPath P4BIN bin.win98 ] ;
		ALL_LOCATE_TARGET = $(EXEC) ;

		OPTIM = /O2 ;
		if $(TYPE_DEBUG) = true { OPTIM += /Zi ; }

		RCFLAGS = /d NDEBUG /r ;
		$(GENFLAGS) += /MD ;
		LINKFLAGS = /MAP ;
	    }
	    else
	    {
		# Static link version, for command line products

		OPTIM = /O2 /Z7 ;
		RCFLAGS = /d NDEBUG /r ;
		$(GENFLAGS) += /MT ;
		LINKFLAGS += /MAP ;
	    }

	case QNXNTO* :
		CC         = cc ;
		C++        = cc ;
		LINKLIBS  += -lsocket ;

	case SCO* :
	    C++ = gcc ;
	    CC = gcc ;
	    LINK = gcc ;
	    LINKLIBS += -lsocket ;

	case SOLARIS* :
		switch $(OSCOMP)
		{
		case SUNC11 : # Sun Studio 11
			# Recommended jam flags: -sOSCOMP=SUNC11 -sBUILD=suncc
			# Add -sTYPE=pic for api.
			CC   = CC ;
			C++  = CC ;
			LINK = CC ;
			OPTIM = -xO3 ;

			if $(TYPE) = pic { OPTIM += -KPIC ; }

			switch $(OSPLAT)
			{
			case *64 :
				$(GENFLAGS) += -xarch=generic64 ;
				LINKFLAGS   += -xarch=generic64 ;
			}

		case SUNC12 : # Sun Studio 12
			# Recommended jam flags: -sOSCOMP=SUNC12 -sBUILD=suncc
			# Add -sTYPE=pic for api.
			CC   = CC ;
			C++  = CC ;
			LINK = CC ;
			OPTIM = -xO3 ;

			if $(TYPE) = pic { OPTIM += -KPIC ; }

			switch $(OSPLAT)
			{
			case *64 :
				$(GENFLAGS) += -m64 ;
				LINKFLAGS   += -m64 ;
			}

		case * : # GCC
			CC   = gcc ;
			C++  = g++ ;
			LINK = gcc ;

			switch $(OSPLAT)
			{
			case *64 : # X86_64 or SPARC64
				LINKFLAGS   += -m64 ;
				$(GENFLAGS) += -m64 ;
			}

			# supc++ needed for all apps since we use gcc >= 3.2.
			LINKLIBS += -lsupc++ ;
		}

		$(GENFLAGS) += -Dsolaris
		               -D_LARGEFILE64_SOURCE
		               -I/opt/lude/include ;

		LINKLIBS += -lsocket -lnsl ;
		AR        = /usr/ccs/bin/ar ru ;
		STRIP     = /usr/ccs/bin/strip ;

		QTOPENGL ?= no ;

	case * :
	    Exit Don't know "$(OS)$(OSVER) or " $(OS) ;
	}

#################################################
#
# Section 5.  Perforce-special rules and actions.
#
#################################################

	#
	# Special Rules
	#
	# FRemoveAny x : y ;    # return new array of x minus any values in y
	# DefineVar src : var ; # define a var for src compilation
	# Ident exe ; -- define bits for program ident string
	# LinkP4WebMacOptions exe ; - adjusting LINKLIBS/LINKFLAGS
	# ListAC ??? ;
	# P4ClientHdrs ; - add all p4 client headers for building Web, ftp
	# P4Library lib : src ; - Library of P4 client libs
	# P4DLibrary lib : src ; - Library of P4D server libs
	# Strip exe ; strip executable of symbols after building
	# CopyRec target : dstdir : srcdir ; recursively copy srcdir into dstdir
	#
	# And build packaging rules
	#
	# P4APIMakeDir apiname : files ; build api dist structure
	# P4Api apiname : files ; make archive files of api dist structure
	# MakeP4ThumbTar ; create p4vthumb.tgz on unix systems
	# MakeP4Vtar ; create p4v.tgz on unix systems
	# MakeP4Vdmg ; create P4V.dmg on Mac OSX
	# MacP4Vassistant target : apps ; install Qt assistant in apps

	rule FRemoveAny
	{
		# Usage: y = [ FRemoveAny $(x) : v1 v2 ... ] ;
		# returns new array with any occurence of v1, v2, etc from $(x) elided
		local _new ;
		local _elt ;
		for _elt in $(1)
		{
			if ! ( $(_elt) in $(2) ) { _new += $(_elt) ; }
		}
		return $(_new) ;
	}

	rule DefineVar
	{
		# Usage: DefineVar foo.cc : VARNAME
		# Defines it if set

		if $($(>))
		{
		    ObjectDefines $(<) :
			[ Fconcat $(>)= [ FQuote \"$($(>))\" ] ] ;
		}
	}

	rule Ident
	{
		# Set up special defines

		local osid = $(OS)$(OSVER:E)$(OSPLAT:E) ;

		rule Fconcat { return $(<:J) ; }

		ObjectDefines $(<) :
		    [ Fconcat ID_OS= 	[ FQuote $(osid[1]:U) ] ]
		    [ Fconcat ID_REL= 	[ FQuote $(RELEASE:J=.) ] ]
		    [ Fconcat ID_PATCH= [ FQuote $(PATCHLEVEL)$(SPECIAL:E) ] ]
		    [ Fconcat ID_Y= 	[ FQuote $(SUPPDATE[1]) ] ]
		    [ Fconcat ID_M= 	[ FQuote $(SUPPDATE[2]) ] ]
		    [ Fconcat ID_D= 	[ FQuote $(SUPPDATE[3]) ] ] ;

		# Source file includes Version

		Includes [ FGristSourceFiles $(<) ] : Version ;
	}

	rule ListAC
	{
		# Special jam trickery to display AC numbers with "jam AC"

		NOTFILE $(<) ;
		ALWAYS $(<) ;
		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		Depends $(<) : $(>) ;
	}

	actions ListAC
	{
		$(AWK) 'BEGIN {L=0; FS=","} /AC_/ {print L, $1; L++}' $(>)
	}

	rule MacRes
	{
		local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
		Depends $(_t) : $(>) ;
		SEARCH on $(>) = $(SEARCH_SOURCE) ;
	}

	rule MacCreatorCode
	{
		switch $(<)
		{
		    case p4v :
		    	return P4VC ;

		    case p4merge :
		    	return P4MG ;

		    case * :
		    	return ttxt ;
		}
	}

	rule P4ClientHdrs
	{
		# P4ClientHdrs ; - add p4 client headers for building Web, ftp

		SubDirHdrs $(P4) client ;
		SubDirHdrs $(P4) diff ;
		SubDirHdrs $(P4) i18n ;
		SubDirHdrs $(P4) middle ;
		SubDirHdrs $(P4) net ;
		SubDirHdrs $(P4) web ;
	}

	rule P4Library
	{
		Library $(<) : $(>) ;
	}

	rule P4DLibrary
	{
		if $(BUILD_P4D) { Library $(<) : $(>) ; }
	}

	rule P4Main
	{
		Main $(<) : $(>) ;
		Strip $(<) ;
		if $(BINDIR) { InstallBin $(BINDIR) : $(<) ; }
	}

	rule P4DMain
	{
		if $(BUILD_P4D)
		{
		    P4Main $(<) : $(>) ;
		}
		else
		{
		    P4NoBuild $(<) : BUILD_P4D ;
		}
	}

	rule P4NoBuild
	{
		NotFile $(>) ;
	}

	actions quietly P4NoBuild
	{
		echo Set $(>) to force build of $(<).
	}

	rule LinkLibraries
	{
		# NB this is superfluous in jam 2.6

		# make library dependencies of target
		# set NEEDLIBS variable used by 'actions Main'

		local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
		local _s = [ FAppendSuffix $(>) : $(SUFLIB) ] ;

		Depends $(_t) : $(_s) ;
		NEEDLIBS on $(_t) += $(_s) ;
	}

	rule Strip
	{
		if $(STRIP) && ( $(TYPE:E=opt) = opt || $(TYPE) = pic )
		{
		    Strip1 $(<:S=$(SUFEXE)) ;
		}
	}

	actions Strip1
	{
		$(STRIP) $(<)
	}

	# CopyRec target : dstdir : srcdir ;
	# Recursively copies the contents of srcdir into dstdir
	# target is a non-file token to use for dependency generation
	rule CopyRec
	{
		local target = $(1) ;
		local dst = [ FDirName $(2) ] ;
		local src = [ FDirName $(3) ] ;

		NotFile $(target) ;

		# ents will be empty if src is not a directory
		local ents = [ Glob $(src) : * ] ; # => src/. src/.. src/a src/b
		if $(ents)
		{
			Depends $(target) : $(dst:G=dir) ;
			MkDir $(dst:G=dir) ;

			ents = [ Match $(src)$(SLASH)(.*) : $(ents) ] ; # => . .. a b

			local sub ;
			for sub in $(ents)
			{
				if $(sub) = $(DOT) || $(sub) = $(DOTDOT) { continue ; }
				CopyRec $(target) : $(dst) $(sub) : $(src) $(sub) ;
			}
		}
		else
		{
			local pdst = $(dst:PG=dir) ;

			Depends $(target) : $(dst) ;
			Depends $(dst) : $(pdst) ;
			MkDir $(pdst) ;

			if $(UNIX)
			{
				# For a recursive copy on unix we want to try to preserve
				# file timestamps and permissions (e.g. they might be
				# executables plain files).
				local CHMOD = ;
				CP on $(dst) = $(CP) -p ;
				File $(dst) : $(src) ;
 			}
			else
			{
				File $(dst) : $(src) ;
			}
		}
	}

	rule P4APIMakeDir
	{
		# P4APIMakeDir apiname : files ;
		#
		# Builds a temp subdirectory $(EXEC)/apiname-releaseinfo
		# and copies the API files into it.
		#
		# Returns a list consisting of the api directory name
		# (usually api-releaseinfo, but possibly
		# api-releasinfo_build_type on NT), and the archive file
		# name (minus final suffix) into which the directory should
		# be stored.
		#
		# This is a subroutine for clarity purposes and probably
		# shouldn't be used directly except by the P4API rule.

		local _cpflags = -p ;    # to preserve times with cp -p
		local _sep = "." ;       # directory name field separator

		if $(VMS)
		{
			_sep = "_" ;
			_cpflags = ;
		}

		# _dirname - apiname-releaseinfo
		# on nt: apiname-releaseinfo-build_type
		local _dirname = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ;
		_dirname = $(<)-$(_dirname:J=$(_sep)) ;
		local _arcname = $(<) ;
		if $(NT)
		{
			local _ntsuffix ;

			switch $(TYPE)
			{
			case dyn* : _ntsuffix = $(BUILD) $(TYPE) ;
			case opt  : _ntsuffix = $(BUILD) static ;
			case *    : _ntsuffix = $(BUILD) static $(TYPE) ;
			}

			_dirname = $(_dirname)-$(_ntsuffix:J=_) ;
			_arcname = $(<)_$(_ntsuffix:J=_) ;
			_cpflags = ;
		}

		NotFile api ;
		Depends all : api ;

		MakeLocate $(_dirname) : $(EXEC) ;
		Depends api : $(_dirname) ;

		# SEARCH_SOURCE -- where api files are found (all over)

		local SEARCH_SOURCE =
		    $(HDRS) $(SUBDIRHDRS) $(SUBDIR) $(P4) ;

		# for each target file, copy to named temp directory
		# create mini structure (include/p4, lib, sample directories)

		local _f ;
		for _f in $(>)
		{
		    local _d _t ;

		    # Note that for .h and .cc files we use different
		    # grist $(x:G=alt), to distinguish these targets from
		    # the ones used in compiles.  We don't want #include
		    # processing on these.

		    switch $(_f)
		    {
		    case *.h   : _d = include p4 ; _f = $(_f:G=alt) ;
		    case *.a   : _d = lib        ;
		    case *.lib : _d = lib        ;
		    case *.olb : _d = lib        ;  # VMS library archive
		    case *.cc  : _d = sample     ; _f = $(_f:G=alt) ;
		    case *     : _d = sample     ;
		    }

		    _t = $(_f:G=$(<)) ;			                # target
		    _d = [ FDirName $(EXEC) $(_dirname) $(_d) ] ;	# directory

		    CP on $(_t) = $(CP) $(_cpflags) ;
		    MakeLocate $(_t) : $(_d) ;
		    File $(_t) : $(_f) ;
		    Depends api : $(_t) ;
		    Clean clean : $(_t) ;
		}

		return $(_dirname) $(_arcname) ;
	}

	rule P4Api
	{
		# P4Api apiname : files ;
		#
		# Builds a temporary subdirectory $(EXEC)/apiname-releaseinfo
		# and makes a tarball apiname.tar of that stuff.

		# _dirname - apiname-releaseinfo
		# on nt: apiname-releaseinfo-build_type
		local _apidata = [ P4APIMakeDir $(<) : $(>) ] ;
		local _dirname = $(_apidata[1]) ;
		local _arcname = $(_apidata[2]) ;

		local _tar     = $(_arcname:S=.tar) ;
		local _tgz     = $(_arcname:S=.tgz) ;
		local _zip     = $(_arcname:S=.zip) ;
		local _bck     = $(_arcname:S=.bck) ;
		local _targets = $(_tar) $(_tgz) $(_zip) ;

		if $(NT)
		{
			# This allows one to still be able to run the
			# command "jam p4api.tar" and have it work, even
			# though the actual file name will vary.
			Depends $(<:S=.tar) : $(_tar) ;
			Depends $(<:S=.tgz) : $(_tgz) ;
			Depends $(<:S=.zip) : $(_zip) ;
		}
		else if $(VMS)
		{
			_targets += $(_bck) ;
		}

		LOCATE on $(_targets) = $(EXEC) ;
		Depends $(_targets) : api ;

		MkTarArchive $(_tar) : $(_dirname) ;
		MkComressedTarArchive $(_tgz) : $(_dirname) ;
		MkZipArchive $(_zip) : $(_dirname) ;
		if $(VMS) { MkBckArchive $(_bck) : $(_dirname) ; }
	}

	rule MakeP4ThumbTar
	{
		local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ;
		local dirname = p4thumb-$(release_info:J=.) ;

		local bindir = $(EXEC) $(dirname) bin ;
		local libdir = $(EXEC) $(dirname) lib p4v ;

		MakeLocate $(dirname) : $(EXEC) ;
		Depends p4thumbtar : $(dirname) ;

		CopyRec p4thumbtar : $(bindir) p4thumb.bin : p4thumb ;
		CopyRec p4thumbtar : $(bindir) p4thumb     : $(AllP4) p4-qt apps p4v p4vwrapper.sh ;

		if $(TYPE_DYNAMIC)
		{
			CopyRec p4thumbtar : $(libdir) qt4 : $(EXEC_LIB) qt4 ;

			local qtconf = <p4thumb>qt.conf ;
			MakeLocate $(qtconf) : [ FDirName $(bindir) ] ;
			Depends p4thumbtar : $(qtconf) ;
			MakeP4VUnixqtconf $(qtconf) ;
			MODE on $(qtconf) = $(FILEMODE) ;
			Chmod $(qtconf) ;
		}

		STRIP on [ FDirName $(bindir) p4thumb.bin ] = $(STRIP) -x ;
		Strip1 [ FDirName $(bindir) p4thumb.bin ] ;

		local _tgz = p4thumb.tgz ;
		LOCATE on $(_tgz) = $(EXEC) ;
		Depends $(_tgz) : p4thumbtar ;
		Depends all : $(_tgz) ;
		MkComressedTarArchive $(_tgz) : $(dirname) ;
	}

	rule MakeP4Vtar
	{
		local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ;
		local dirname = p4v-$(release_info:J=.) ;

		local bindir = $(EXEC) $(dirname) bin ;
		local libdir = $(EXEC) $(dirname) lib p4v ;

		MakeLocate $(dirname) : $(EXEC) ;
		Depends p4vtar : $(dirname) ;

		# P4V components and help
		CopyRec p4vtar : $(bindir) p4v.bin                         : p4v ;
		CopyRec p4vtar : $(bindir) p4v                             : $(AllP4) p4-qt apps p4v p4vwrapper.sh ;
		CopyRec p4vtar : $(libdir) P4VResources p4vhelp            : $(AllP4) p4-doc help p4v-html-pure ;
		CopyRec p4vtar : $(libdir) P4VResources icons              : $(AllP4) p4-doc help icons ;
		CopyRec p4vtar : $(libdir) P4VResources p4vhelp p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ;

		# P4Merge components and help
		CopyRec p4vtar : $(bindir) p4merge.bin                     : p4merge ;
		CopyRec p4vtar : $(bindir) p4merge                         : $(AllP4) p4-qt apps p4v p4vwrapper.sh ;
		CopyRec p4vtar : $(libdir) P4VResources p4mergehelp        : $(AllP4) p4-doc help p4merge ;

		if $(TYPE_DYNAMIC)
		{
			CopyRec p4vtar : $(libdir) qt4       : $(EXEC_LIB) qt4 ;
			CopyRec p4vtar : $(bindir) assistant : $(EXEC_LIB) assistant_dyn ;

			local qtconf = <p4v>qt.conf ;
			MakeLocate $(qtconf) : [ FDirName $(bindir) ] ;
			Depends p4vtar : $(qtconf) ;
			MakeP4VUnixqtconf $(qtconf) ;
			MODE on $(qtconf) = $(FILEMODE) ;
			Chmod $(qtconf) ;
		}
		else
		{
			CopyRec p4vtar : $(bindir) assistant : $(EXEC_LIB) assistant ;
		}

		STRIP on [ FDirName $(bindir) p4v.bin ] = $(STRIP) -x ;
		Strip1 [ FDirName $(bindir) p4v.bin ] ;

		STRIP on [ FDirName $(bindir) p4merge.bin ] = $(STRIP) -x ;
		Strip1 [ FDirName $(bindir) p4merge.bin ] ;

		local _tgz = p4v.tgz ;
		LOCATE on $(_tgz) = $(EXEC) ;
		Depends $(_tgz) : p4vtar ;
		Depends all : $(_tgz) ;
		MkComressedTarArchive $(_tgz) : $(dirname) ;
	}

	rule MakeP4Vdmg
	{
		local target = P4V.dmg ;
		local apps = p4v p4merge ;

		LOCATE on $(target) = $(EXEC) ;
		Depends $(target) : p4vdmg ;
		Depends p4vdmg : $(apps) ;

		#
		# Prep for p4v.app
		#

		local dir = $(EXEC) p4v.app Contents ;
		if $(TYPE_DYNAMIC)
		{
			CopyRec p4vdmg : $(dir) Frameworks : $(EXEC_LIB) Frameworks ;
			CopyRec p4vdmg : $(dir) PlugIns    : $(EXEC_LIB) PlugIns ;
		}

		dir = $(dir) Resources ;
		CopyRec p4vdmg : $(dir) icons           : $(AllP4) p4-doc help icons ;
		CopyRec p4vdmg : $(dir) Help            : $(AllP4) p4-doc help p4v-html-pure ;
		CopyRec p4vdmg : $(dir) Help p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ;

		#
		# Prep for p4merge.app
		#

		dir = $(EXEC) p4merge.app Contents ;
		if $(TYPE_DYNAMIC)
		{
			CopyRec p4vdmg : $(dir) Frameworks : $(EXEC_LIB) Frameworks ;
			CopyRec p4vdmg : $(dir) PlugIns    : $(EXEC_LIB) PlugIns ;
		}

		dir = $(dir) Resources ;
		CopyRec p4vdmg : $(dir) Help          : $(AllP4) p4-doc help p4merge ;
		CopyRec p4vdmg : $(dir) launchp4merge : p4merge_mac_shim ;

		#
		# Fixup dynamic library references for both apps and copy
		# in version check stub.
		#

		if $(TYPE_DYNAMIC)
		{
			local _bin ;
			for _bin in $(apps)
			{
				local _old = [ FDirName $(EXEC) $(_bin:S=.app) Contents MacOS $(_bin) ] ;
				# Must use the same grist here as in QtMacPackage.
				_old = $(_old:G=$(_bin)) ;
				local _new = $(_old).real ;

				Depends p4vdmg : $(_new) ;
				Depends $(_new) : $(_bin) ;
				MacP4VdyldFixup $(_new) : $(_bin) ;

				MacP4Vqtconf p4vdmg : $(_bin) : [ FDirName $(EXEC) $(_bin:S=.app) ] ;
			}
		}

		MacP4Vassistant p4vdmg : $(apps) ;
		buildDMG $(target) : $(EXEC:G=dir)/$(apps:S=.app) ;
 	}

	# Install dynamic or static version of the assistant.
	# The assistant comes straight from the TrollTech distribution for
	# now, though someday we may make our own branded version.
	rule MacP4Vassistant
	{
		local _assistant_src _app ;
		if $(TYPE_DYNAMIC)
		{
			_assistant_src = assistant_dyn.tar ;
		}
		else
		{
			_assistant_src = assistant.tar ;
		}
		LOCATE on $(_assistant_src) = $(EXEC_LIB) ;

		ASSISTANT_ICONS on     <p4v>assistant.app = $(AllP4)/p4-qt/apps/p4v/img/p4v_help.icns ;
		ASSISTANT_ICONS on <p4merge>assistant.app = $(AllP4)/p4-qt/apps/p4merge/img/p4_merge_help.icns ;

		for _app in $(>)
		{
			local _dst = <$(_app)>assistant.app ;
			local _dstdir = [ FSubDirPath $(EXEC_TOKENS) $(_app:S=.app) Contents Resources ] ;
			MakeLocate $(_dst) : $(_dstdir) ;
			Depends $(<) : $(_dst) ;
			Depends $(_dst) : $(_assistant_src) ;
			MacP4Vassistant_install $(_dst) : $(_assistant_src) ;

			if $(TYPE_DYNAMIC)
			{
				MacP4Vqtconf $(<) : $(_dst) : [ FDirName $(_dstdir) assistant.app ] ;
			}
		}
	}

	rule MacP4Vqtconf
	{
		local qtconf    = <$(3)>qt.conf ;
		local qtconfdir = [ FDirName $(3) Contents Resources ] ;

		LOCATE on $(qtconf) = $(qtconfdir) ;
		Depends $(1) : $(qtconf) ;
		Depends $(qtconf) : $(2) ;
		MakeP4VMacqtconf $(qtconf) ;
		MODE on $(qtconf) = $(FILEMODE) ;
		Chmod $(qtconf) ;
	}

	actions MacP4Vassistant_install
	{
		tar -xpvf $(>) -C $(<:P)
		cp $(ASSISTANT_ICONS) $(<)/Contents/Resources/assistant.icns
	}

	# The copying of SystemVersionCheck ideally should be a separate
	# rule/action, but it's difficult to get Jam to replace one file
	# with another except incidentally, and here we are kind of moving
	# (and modifying) the original target, so here is as good a place
	# as any to do it.
	actions MacP4VdyldFixup
	{
		$(CP) -p "$(>)" "$(<)" || exit 1
		otool -X -L "$(<)" \
		  | sed -e '/@executable_path/d' \
		        -e '/Qt[^.\/]*\.framework/!d' \
		        -e 's/ *(compat.*//' \
		        -e 's/^[ 	]*//' \
		  | while read dep ; do
		      toprel=`echo "$dep" | sed -e 's=.*/\([^/]*.framework/\)=\1='`
		      new=@executable_path/../Frameworks/$toprel
		      install_name_tool -change "$dep" "$new" "$(<)"
		    done
		$(CP) $(EXEC_LIBEXEC)/SystemVersionCheck "$(>)"
	}

	actions MakeP4VUnixqtconf
	{
		echo "[paths]" > $(<)
		echo "plugins = ../lib/p4v/qt4/plugins" >> $(<)
	}

	actions MakeP4VMacqtconf
	{
		echo "[paths]" > $(<)
		echo "plugins = PlugIns" >> $(<)
	}

	actions buildDMG
	{
		$(AllP4)/tools/scripts/buildDMG.pl \
			-debug \
			-compressionLevel 9 \
			-buildDir $(EXEC) \
			-dmgName $(<:B) \
			-volName $(<:B) \
			$(>)
	}

	actions MkTarArchive
	{
		tar -cf $(<) -C $(>:P) $(>:BE)$(>:SE)
	}

	actions MkZipArchive
	{
		cd $(<:P)
		zip -9 -r -q $(<:BE)$(<:SE) $(>:BE)$(>:SE)
	}

	actions MkComressedTarArchive
	{
		tar -cf - -C $(>:P) $(>:BE)$(>:SE) | $(COMPRESS) > $(<)
	}

	rule LinkSmartHeap
	{
          if $(SMARTHEAP) = yes
          {
            local _64 = "" ;
            local   d = "" ;

            if $(OSPLAT) = X86_64 || $(OSPLAT) = X64 { _64 = 64 ; }

            if $(TYPE) = g { d = d ; }

            switch $(OS)-$(OSVER:E)-$(OSPLAT:E)-$(OSCOMP:E)
            {
              case NT-*-*-* :
                SMARTHPLIB ?= $(EXEC_LIB)\\shlSMP$(_64)Mt$(d).lib ;

              local e = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
              LINKLIBS on $(e) = setargv.obj $(SMARTHPLIB)
                                 advapi32.lib oldnames.lib
                                 kernel32.lib ws2_32.lib ;

              case LINUX-*-*-* :
                SMARTHPLIB ?= $(EXEC_LIB)/libsmartheapC$(d)$(_64).a
                              $(EXEC_LIB)/libsmartheap$(d)$(_64).a ;

              # Per-target LINKLIBS need to incorporate global libs
              # too (e.g. libsupc++), but they should come after the
              # smartheap libs.
              LINKLIBS on $(<) += $(SMARTHPLIB) $(LINKLIBS) ;
            }
          }
        }

#################################################
#
# Section 5.  Perforce-special Windows rules.
#
#################################################

	#
	# Special p4-win/scc/p4-exp rules:
	#
	# P4EXPCompileActions - quotes STDHDRS
	# P4EXPIncludes - set up headers fpr WTL and platform SDK
	# P4EXPDefines - set C++ flags for P4-EXP
	# P4EXPDOTH file : file ; - wrapper for p4exp.h dependencies
	# P4EXPDOTHDEPENDS files : file ; - wrapper for files dependant on p4exp.h
	# P4EXPMIDL file : file ; - set up files for MIDL compiling
	# EXPMIDL file : file ; - compile .idl file
	# EXP64MIDL file : file ; - compile .idl file for 64 bit Windows
	# P4EXPLinkage exe : libs ; - set up link flags windows exe
	#
	# P4SccDefines - set C++ flags for (old) p4scc.dll
	#
	# P4WinDefines - set C++ flags for p4-win/gui
	# P4WinDiffDefines - set C++ flags for p4-win/diff, merge
	#
	# WinDefines opts : defines ; - set C++ flags for p4-win
	# WinDllDeffile exe : file ; - set /def: file for link
	# WinDllLinkage exe : libs ; - set up link flags windows DLL
	# WinDllNoMain exe ; - setup exe with no main
	# WinLinkage exe : libs ; - set up link flags windows exe
	# WinRes exe : *.rc : flags ; - compile .rc->.res, link against exe
	# WinResIdent *.rc ; - set special defines for build identification
	#

	rule P4RPTCLILinkage
	{
	    local _lf = /subsystem:console ;

	    switch $(TYPE_DEBUG)
	    {
	    case true : _lf += /DEBUG ;
	    case *    : _lf += /MAP ;
	    }

	    _lf += /INCREMENTAL:NO ;
	    _lf += /NODEFAULTLIB:"libcmt" ;
	    _lf += /NODEFAULTLIB:"libc" ;

	    switch $(OSPLAT)
	    {
	    case X86 : _lf += /MACHINE:x86 ;
	    }

	    LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ;

	    LINKLIBS on $(<) =
	    gdi32.lib comctl32.lib shlwapi.lib user32.lib
	    version.lib shell32.lib advapi32.lib oldnames.lib
	    kernel32.lib ws2_32.lib winmm.lib odbc32.lib
	    odbccp32.lib $(2) ;
	}

	rule P4GTLinkage
	{
	    local _lf = /subsystem:windows ;

	    switch $(TYPE_DEBUG)
	    {
	    case true : _lf += /DEBUG ;
	    case *    : _lf += /MAP ;
	    }

	    _lf += /DLL ;
	    _lf += /INCREMENTAL:NO ;
	    _lf += /NODEFAULTLIB:"libcmt" ;
	    _lf += /NODEFAULTLIB:"libc" ;

	    switch $(OSPLAT)
	    {
	    case X86 : _lf += /MACHINE:x86 ;
	    }

	    LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ;

	    LINKLIBS on $(<) =
	    $(P4GT)/htmlhelp/htmlhelp.lib
	    gdi32.lib comctl32.lib shlwapi.lib user32.lib
	    version.lib shell32.lib advapi32.lib oldnames.lib
	    kernel32.lib ws2_32.lib winmm.lib odbc32.lib
	    odbccp32.lib $(2) ;
	}

	rule P4GTDefines
	{
	    WinDefines /GR /GX : _USRDLL _WINDLL NT_PLUGIN ;
	}

	rule P4EXPCompileActions
	{

		actions C++
		{
			$(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) "/I$(STDHDRS)" /Tp$(>)
		}

		actions Cc
		{
			$(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) "/I$(STDHDRS)" $(>)
		}
	}

	rule P4EXPIncludes
	{
		P4ClientHdrs ;
		STDHDRS += "C:\\Program Files\\Microsoft SDK\\include" ;
	}

	rule P4EXPDefines
	{
		local u = ;

  		if $(OSVER) != 98 && ! $(NOUNICODE)
		{
   			u += [ FDefines UNICODE _UNICODE ] ;
  		}

		WinDefines /Ob1 /EHsc $(u) : _UNICODE _ATL_STATIC_REGISTRY _USRDLL _WINDLL ;
	}

	rule P4EXPDOTH
	{
		DEPENDS $(<) : $(>) ;
		Clean clean : $(<) ;
	}

	rule P4EXPDOTHDEPENDS
	{
		DEPENDS $(<) : $(>) ;
	}

	rule P4EXPMIDL
	{
		DEPENDS $(<) : $(>) ;

		switch $(OSPLAT)
		{
		case X64 : EXP64MIDL $(<) : $(>) ;
		case *   : EXPMIDL $(<) : $(>) ;
		}

		Clean clean : $(<) p4exp.tlb dlldata.c p4exp_p.c ;
	}

	actions EXPMIDL
	{
		midl /env win32 /Oicf /tlb ".\p4exp.tlb" /h "p4exp.h" /iid $(<) $(>)
	}

	actions EXP64MIDL
	{
		midl /env x64   /Oicf /tlb ".\p4exp.tlb" /h "p4exp.h" /iid $(<) $(>)
	}

	rule P4EXPLinkage
	{
		# P4EXPLinkage exe : libs ; - set up link flags windows exe

		local _lf = /subsystem:windows ;

		switch $(TYPE_DEBUG)
		{
		case true : _lf += /DEBUG ;
		case *    : _lf += /MAP ;
		}

		_lf += /DLL ;
		_lf += /def:p4exp.def ;

		switch $(OSPLAT)
		{
		case X86 : _lf += /MACHINE:X86 ;
		}

		LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ;

		LINKLIBS on $(<) =
			gdi32.lib comctl32.lib shlwapi.lib
			user32.lib version.lib shell32.lib
			advapi32.lib oldnames.lib kernel32.lib ws2_32.lib
			winmm.lib $(2) ;

	}

	rule P4SccDefines
	{
		WinDefines /GX : _USRDLL _WINDLL ;
	}

	rule P4WinDefines
	{
		local u = ;

		# Unicode builds except on Win98.

		if $(OSVER) != 98 && ! $(NOUNICODE)
		{
			u += [ FDefines UNICODE _UNICODE ] ;
		}
		else
		{
			u += [ FDefines _MBCS ] ;
		}

		u += /GR /EHsc /GS ;
		if $(TYPE_DEBUG) = true { u += /Zi ; }

		WinDefines $(u) : STRICT ;
	}

	rule P4WinDiffDefines
	{
		WinDefines /GR /GX : P4DIFF ;
	}

	rule WinDefines
	{
		SubDirC++Flags
		    /W3 $(1)
		    [ FDefines NDEBUG _WINDOWS $(2) ] ;

		switch $(OSPLAT)
		{
		case X64 : SubDirC++Flags [ FDefines WIN64 ] ;
		case *   : SubDirC++Flags [ FDefines WIN32 ] ;
		}

		if $(TYPE_DYNAMIC)
		{
		    SubDirC++Flags [ FDefines _AFXDLL ] ;
		}
	}

	rule WinDllDeffile
	{
		# WinDllDeffile exe : file ; - set /def: file for link

		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		DEFFILE on $(<) = $(>) ;
		DEPENDS $(<) : $(>) ;
	}

	rule WinDllLinkage
	{
		# WinDllLinkage exe : libs ; - set up link flags windows DLL

		WinLinkage $(<) : $(>) ;

		LINKFLAGS on $(<) += /dll ;
	}

	rule WinDllNoMainLinkage
	{
		# WinDllNoMain exe ;

		LINKFLAGS on $(<) += /NOENTRY /SUBSYSTEM:WINDOWS /DLL ;

		switch $(OSPLAT)
		{
		case X64 : LINKFLAGS on $(<) += /MACHINE:X64 ;
		case *   : LINKFLAGS on $(<) += /MACHINE:I386 ;
		}

		LINKLIBS on $(<) = $(2) ;
	}

	rule WinLinkage
	{
		# WinLinkage exe : libs ; - set up link flags windows exe

		local _lf = /subsystem:windows ;

		switch $(TYPE_DEBUG)
		{
		case true : _lf += /DEBUG ;
		case *    : _lf += /MAP /DEBUG ;
		}

		if $(OSVER) != 98 && ! $(NOUNICODE)
		{
			_lf += /ENTRY:"wWinMainCRTStartup" ;
		}

		switch $(OSPLAT)
		{
		case X86 : _lf += /MACHINE:X86 ;
		}

		LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ;

		LINKLIBS on $(<) =
		    $(2) ;
	}

	rule WinRes
	{
		# WinRes exe : *.rc : flags ; - compile .rc->.res, link

		# Compile .rc into .res for linking into executable.
		# (Strictly MSVCNT, I presume.)

		local s r e ;

		e = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
		s = [ FGristSourceFiles $(>) ] ;
		r = $(s:S=.res:G=) ;

		DEPENDS $(e) : $(r) ;
		DEPENDS $(r) : $(s) ;

		LinkLibraries $(e) : $(r) ;

		LOCATE on $(r) = $(LOCATE_TARGET) ;
		SEARCH on $(s) = $(SEARCH_SOURCE) ;

		# .rc files have #includes, but we're pretty sure
		# they include only files local to the .rc's directory

		HDRRULE on $(>) = HdrRule ;
		HDRSCAN on $(>) = $(HDRPATTERN) ;
		HRDSEARCH on $(>) = $(SEARCH_SOURCE) ;
		HDRGRIST on $(>) = $(HDRGRIST) ;

		# Bind headers

		RCFLAGS on $(r) = $(RCFLAGS) $(3) ;
		RCHDRS on $(r) = [ on $(r) FIncludes
			$(SUBDIRHDRS) $(HDRS) $(STDHDRS) ] ;

		WinRc $(r) : $(s) ;

		Clean clean : $(r) ;
	}

	rule WinResIdent
	{
		# WinResIdent *.rc ;

		local s r p v ;

		s = [ FGristSourceFiles $(<) ] ;
		r = $(s:S=.res:G=) ;

		# If RELEASE=2005.1 and PATCHLEVEL=69929 then
		#	P4_FILE_VERSION = 2005.1.6.9929
		#	P4_PRODUCT_VERSION = 2005.1

		p = [ Match (.*)(....) : $(PATCHLEVEL) ] ;
		v = $(RELEASE[1]).$(RELEASE[2]).$(p:J=.) $(RELEASE[3]) ;

		rule Fconcat { return $(<:J) ; }

		RCFLAGS on $(r) += [ FDefines
		    [ Fconcat P4_INT_MAJOR= $(RELEASE[1]) ]
		    [ Fconcat P4_INT_MINOR= $(RELEASE[2]) ]
		    [ Fconcat P4_INT_HBUILD= $(p[1]) ]
		    [ Fconcat P4_INT_LBUILD= $(p[2]) ]
		    [ Fconcat P4_FILE_VERSION= [ FQuote $(v[1]) ] ]
		    [ Fconcat P4_PRODUCT_VERSION= [ FQuote $(v:J=.) ] ]
		    [ Fconcat P4_COPYRIGHT= [ FQuote $(RELEASE[1]) ] ]
		    ] ;

		# Source file includes Version

		Includes $(s) : Version ;
	}

	actions WinRc {
		rc /fo $(<) $(RCFLAGS) "$(RCHDRS)" $(>)
	}


#################################################
#
# Section 7.  QT build rules and actions.
#
#################################################

	#
	# QtDefines ; - Add defines/headers for building with QT
	# QtEmbed x.h : files : flags ; - preprocess with qembed
	# QtFormLibrary lib : *.ui ; make .h's and archive .obj's
	# QtHeaders ts : headers ; - list headers for i18n xlation
	# QtImages x.h : files ; - make a .h from image files
	# QtLibrary lib : ts : files ; - Library call with lupdate
	# QtLinkage exe : opt ; - linkflags/libs for building with QT
	# QtConsoleLinkage exe ; - QtLinkage for a console app on NT
	# QtLrelease qm : ts ; - build qm from ts files with lrelease
	# QtMoc x.cpp : x.h ; - preprocess with moc
	# QtMocLibrary lib : *.h ; - moc, compile, & archive
	# QtResource qrc : mod : pngs ; - name pngs to make resource
	# QtResourceCpp cpp : qrc ; - build .cpp from resource file
	# QtUicCpp x.cpp : x.ui x.h ; - preprocess with uic to make .cpp
	# QtUicHdr x.h : x.ui ; - preprocess with uic to make .h
	#

	QtLanguages = jp la ;

	rule QtHeaders
	{
		# QtHeaders ts : headers ; - list headers for lupdate

		# This just stashes the named headers in the QTLUPHDRS
		# variable, used by QtLupdate1 to generate the translation
		# files.

		# We give the headers a separate grist, so that we don't
		# confuse their other uses (just in case we mess up here).

		QtLupdate $(<) : h : $(>:G=QTLHDR) ;
	}

	rule QtLibrary
	{
		# QtLibrary lib : ts : files ; - Library call with lupdate

		Library $(1) : $(3) ;
		QtLupdate $(2) : s : [ FGristSourceFiles $(3) ] ;
	}

	rule QtLrelease
	{
		# QtLrelease qm : ts ;

		for _i in $(QtLanguages)
		{
		    QtLreleaseRun $(1)_$(_i).qm : $(2)_$(_i).ts ;
		}

		LOCATE on $(_ts) $(_qm) = $(LOCATE_TARGET) ;

	}

	rule QtLreleaseRun
	{
		# QtLreleaseRun qm : ts ;

		NotFile lupdate ;
		Depends lupdate : $(1) ;
		Depends $(1) : $(2) ;

		LOCATE on $(1) $(2) = $(LOCATE_TARGET) ;
	}

	actions QtLreleaseRun
	{

		$(QTLREL) $(>) -qm $(<)
	}

	rule QtLupdate
	{
		# QtLupdate ts : h/s : files ; - Add sources/hdrs to lupdate

		local _ts = $(1)_$(QtLanguages).ts ;

		local _pro = $(1).pro ;
		local _proh = $(1)h.pro ;
		local _pros = $(1)s.pro ;
		local _prox = $(1)$(2).pro ;

		on $(_ts) if ! $(Done)
		{
		    Done on $(_ts) = true ;

		    # .ts -> .pro -> s.pro (QtLupTmp)-> sources
		    #		  -> h.pro (QtLupTmp)-> headers

		    NotFile lupdate ;
		    Depends lupdate : $(_ts) ;
		    Depends $(_ts) : $(_pro) ;
		    Depends $(_pro) : $(_proh) $(_pros) ;

		    # _pro must be in current directory
		    # or lupdate gets confused.

		    LOCATE on $(_ts) $(_proh) $(_pros) = $(LOCATE_TARGET) ;
		    QTLTRANS on $(_pro) = $(_ts) ;

		    # Build ts files from pro file
		    # Build pro file from list of headers/sources

		    QtLupdateRun $(_ts) : $(_pro) ;
		    QtLupdatePro $(_pro) : $(_proh) $(_pros) ;

		    # Zonk pro files when done

		    RmTemps $(_ts) : $(_pro) ;
		    RmTemps $(_pro) : $(_proh) $(_pros) ;

		    # Zero h.pro/s.pro files to begin with

		    QtLupTmp0 $(_proh) ;
		    QtLupTmp0 $(_pros) ;
		}

		# Add files to building or h.pro/s.pro file

		Depends $(_prox) : $(3) ;
		SEARCH on $(3) = $(SEARCH_SOURCE) ;
		QtLupTmp1 $(_prox) : $(3) ;
	}


	# QtLupdatePro pro : hpro spro ;

	if $(OS) = NT
	{
	    actions quietly together piecemeal QtLupTmp1
	    {
		    echo $(>) \ >> $(<)
	    }

	    actions quietly QtLupTmp0
	    {
		    echo. > $(<)
		    $(RM) $(<)
	    }

	    actions quietly QtLupdatePro bind QTLTRANS
	    {
		    echo TRANSLATIONS = $(QTLTRANS) > $(<)
		    echo HEADERS = \ >> $(<)
		    type $(>[1]) >> $(<)
		    echo. >> $(<)
		    echo SOURCES = \ >> $(<)
		    type $(>[2]) >> $(<)
		    echo. >> $(<)
	    }
	}
	else
	{
	    actions quietly together piecemeal QtLupTmp1
	    {
		    echo $(>) \\ >> $(<)
	    }

	    actions quietly QtLupTmp0
	    {
		    $(RM) $(<)
	    }

	    actions quietly QtLupdatePro bind QTLTRANS
	    {
		    echo TRANSLATIONS = $(QTLTRANS) > $(<)
		    echo HEADERS = \\ >> $(<)
		    cat $(>[1]) >> $(<)
		    echo "" >> $(<)
		    echo SOURCES = \\ >> $(<)
		    cat $(>[2]) >> $(<)
		    echo "" >> $(<)
	    }
	}

	# QtLupdateRun ts : pro ;

	actions QtLupdateRun
	{
		$(QTLUP) $(>)
	}

	rule QtBaseDefines
	{
		# QtDefines ; - Add defines/headers for building with QT

		if ! $(QTDIR)
		{
		    Exit Can't build in QT directories without QTDIR set. ;
		}

		if $(JAMVERSION) < 2.4.1 {
		    Exit QT builds require 2.4.1 ;
		}

		if $(JAMBASEDATE) < 2005.05.05 && ! $(QT25WARN) {
		    Echo QT builds work poorly without Jambase 2005.05.05 ;
		    QT25WARN = true ;
		}

		QTLUP    = [ FDirName $(QTDIR) bin lupdate ] ;
		QTLREL   = [ FDirName $(QTDIR) bin lrelease ] ;
		QTMOC    = [ FDirName $(QTDIR) bin moc ] ;
		QTUIC    = [ FDirName $(QTDIR) bin uic ] ;
		QEMBED   = [ FDirName $(QTDIR) bin qembed ] ;

		local _d _f ;

		_d += QT_NO_STL ;
		_d += QT_THREAD_SUPPORT ;
		_d += QT_NO_CAST_TO_ASCII ;
		_d += QT_NO_CAST_FROM_ASCII ;
		_d += QT_STATICPLUGIN ;
		if $(1) = QT3
		{
			_d += QT3_SUPPORT ;
			NEED_QT3SUPPORT = 1 ;
		}

		if $(QTOPENGL) = no
		{
			_d += NO_OPENGL ;
		}

		if $(TEST) { _d += TEST ; }

		# Source code debugging
		# DEBUG is in our code -- conditional compilations
		# QT_NO_* is in QT code

		switch $(TYPE_DEBUG)
		{
		case true : _d += DEBUG ;
		case *    : _d += QT_NO_DEBUG QT_NO_CHECK ;
		}

		switch $(OS)
		{
		case NT :
			_f += /EHsc /GR /W4 ;
			_f += /wd4127 ; # conditional expression is constant
			_f += /wd4512 ; # assignment operator could not be generated

			# from Qt's Makefile
			# but we want stricter warnings and don't use precompiled headers
			# _f += /Zm200 /W3 ;

			if $(MSVSVER) >= 8
			{
				# VS8 treats wchar_t as a builtin type by default
				# while prior version use a typedef
				_f += /Zc:wchar_t- ;
			}
			if $(TYPE_DEBUG)
			{
				# enable runtime checks for debug builds only
				# this isn't compatible with optimizations
				_f += /RTCcsu ;

				if $(VLD)
				{
					_d += VLD ;
				}
			}
		}

		SubDirC++Flags [ FDefines $(_d) ] $(_f) ;
	}
	rule QtCoreHeaders
	{
		QtAllHeaders : Qt QtCore ;
	}
	# If a list of ": modules ..." is specified, just add those directories
	# into the search list.  Otherwise, a default list is generated.
	rule QtAllHeaders
	{
		local QtModules = $(2) ;
 		if ! $(QtModules)
		{
			QtModules =
				Qt
				QtCore
				QtGui
				QtAssistant
				QtNetwork
				QtXml ;
		}

		if $(QTOPENGL) != no
		{
			QtModules += QtOpenGL ;
		}

		if $(1) = QT3
		{
			QtModules = Qt3Support $(QtModules) ;
			NEED_QT3SUPPORT = 1 ;
		}

		for module in $(QtModules)
		{
			SubDirHdrs [ FDirName $(QTDIR) include $(module) ] ;

			# Also search the framework directories so that
			# non-module-qualified #include <QFoo> directives
			# work even when headers are not installed in
			# QTDIR/include/qtmodule.
			if $(OS) = MACOSX && ! $(QT_NO_FRAMEWORK_INCLUDES)
			{
				SubDirHdrs [ FDirName $(QTDIR) lib $(module).framework Headers ] ;
			}

		}
		SubDirHdrs [ FDirName $(QTDIR) include ] ;
		SubDirHdrs $(LOCATE_SOURCE[1]) ;

		if $(OS) = FREEBSD
		{
		    SubDirHdrs /usr/X11R6/include ;
		}
		if $(OS) = NT && $(TYPE_DEBUG) && $(VLD)
		{
			SubDirHdrs $(VLD)/include ;
		}
	}
	rule QtDefines
	{
		# QtDefines ; - Add defines/headers for building with QT
		# Adds headers for all Qt modules
		if $(1) = QT3
		{
			echo including qt3 support for $(SUBDIR) ;
		}
		QtBaseDefines $(1) ;
		QtAllHeaders $(1) ;
	}
	rule QtCoreDefines
	{
		# QtCoreDefines ; - Add defines/headers for building with QT
		# Adds headers for QtCore only; no QtGui or other rot
		QtBaseDefines ;
		QtCoreHeaders ;
	}
	rule QtLinkage
	{
		# QtLinkage exe : opt : qtlibs : rpath ; - linkflags/libs for building with QT

		local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
		local _opt = $(2) ;

		# Executable-local rpaths are only supported by the dynamic
		# linker/loader on solaris and linux so far.  MacOSX also supports
		# them but the syntax and mechanism is different; see MacP4VdyldFixup.
		#
		# Please don't use this parameter for absolute paths; it should be
		# for paths relative to the executable, wherever it is run, a la
		# the linux/solaris $ORIGIN token.
		#
		# Use the literal token "NULL" for rpath arg if you want to supress
		# any dynamic rpath.
		local _rpath = $(4) ;
		if $(_rpath) = "" { _rpath = $ORIGIN/../lib/p4v/qt4/lib ; }

		# The order here is significant when linking statically.
		local QT4LIBLIST ;
		if $(3)
		{
			# If a Qt library list is specified in the 3rd
			# parameter to this rule, we use those and only
			# those libraries.
			QT4LIBLIST = $(3) ;
		}
		else
		{
			# otherwise, we use a library list customized for p4v.

		if $(NEED_QT3SUPPORT)
		{

			QT4LIBLIST += Qt3Support ;
		}
		if $(TESTS) # unit testing
		{
			QT4LIBLIST += QtTest ;
		}

		if $(QTOPENGL) != no
		{
			QT4LIBLIST += QtOpenGL ;
				# $(UNIX) is set even for osx, but we must exclude macs here.
				if $(UNIX) && $(OS) != MACOSX && ! $(TYPE_DYNAMIC)
				{
					# These libraries must be enumerated explicitly because our
					# static production Qt libs depend on them.
					QT4LIBLIST += GL ;
				}
		}

		QT4LIBLIST +=
			QtAssistantClient
			QtXml
			QtNetwork
			QtGui
			QtCore ;
		}

		switch $(OS)
		{
			# We don't want to embed rpath entries for QTDIR/lib in
			# production builds because they are not located in a
			# standard system directory (unlike e.g. /usr/X11R6/lib).
			# Doing so results in unnecessary stat calls on customer
			# filesystems that may even cause network timeouts.  We
			# link Qt statically in unix production builds.
			#
			# Please don't add X libraries here in order to satisfy
			# dependencies in development builds of Qt.  The libraries
			# listed here are the dependencies required for production
			# builds; adding more dynamic linker dependencies
			# decreases portability.
			#
			# If you are working with QT shared libraries in a
			# development environment, there are 3 alternatives:
			#   1. set LD_LIBRARY_PATH
			#   2. edit your system ld.so.conf
			#   3. use the dev_LINKFLAGS and dev_LINKLIBS hooks:
			#         jam -sdev_LINKFLAGS="..." -sdev_LINKLIBS="..."

		case FREEBSD :
			LINKFLAGS on $(_t) +=
				# -Wl,-rpath,$(QTDIR)/lib
				-L$(QTDIR)/lib
				-L/usr/X11R6/lib
				$(LINKFLAGS) $(dev_LINKFLAGS) ;

			if ! $(TYPE_DYNAMIC)
			{
				# These libraries must be enumerated explicitly because our
				# static production Qt libs depend on them.
				QT4LIBLIST +=
					Xrender
					Xrandr
					Xcursor
					fontconfig
					SM
					Xfixes
					X11
					m ;
			}

			LINKLIBS on $(_t) +=
				-l$(QT4LIBLIST)
				-pthread
				/usr/local/lib/libiconv.a
				$(LINKLIBS) $(dev_LINKLIBS) ;

		case SOLARIS :
			LINKFLAGS on $(_t) +=
				-L$(QTDIR)/lib
				-L/usr/X11R6/lib
				-L/usr/openwin/lib
				-L/usr/sfw/lib
				-L/opt/lude/lib
				$(LINKFLAGS) $(dev_LINKFLAGS) ;

			if $(TYPE_DYNAMIC)
			{
				if $(_rpath) != "NULL"
				{
					LINKFLAGS on $(_t) += -Wl,-R,'$(_rpath)' ;
				}
				LINKFLAGS on $(_t) += -Wl,-R,/usr/sfw/lib ;
			}
			else # ! $(TYPE_DYNAMIC)
			{
				# These libraries must be enumerated explicitly because our
				# static production Qt libs depend on them.
				QT4LIBLIST +=
					ICE
					SM
					Xrender
					Xfixes
					Xext
					fontconfig
					freetype
					X11
					rt	;
			}

			LINKLIBS on $(_t) +=
				-l$(QT4LIBLIST)
				-lm -lpthread
				$(LINKLIBS) $(dev_LINKLIBS) ;

		case NETBSD :
			LINKFLAGS on $(_t) +=
				# -Wl,-rpath,$(QTDIR)/lib
				-Wl,-rpath,/usr/X11R6/lib
				-Wl,-rpath,/usr/pkg/lib
				-L$(QTDIR)/lib
				-L/usr/X11R6/lib
				-L/usr/pkg/lib
				$(LINKFLAGS) $(dev_LINKFLAGS) ;

			LINKLIBS on $(_t) +=
				-lqt-mt -lSM -lICE -lXext -lX11
				-lm -lpthread -lXmu -lX11
				-lXrandr -lXcursor -lXrender -lX11
				$(LINKLIBS) $(dev_LINKLIBS) ;

			HDRS += /usr/pkg/include ;

			if ! $(TYPE_DYNAMIC)
			{
				LINKFLAGS on $(_t) += -static ;
			}

		case LINUX :
			if $(TYPE_DYNAMIC) && $(_rpath) != "NULL"
			{
				LINKFLAGS on $(_t) += -Wl,-rpath,'$(_rpath)' ;
			}

			switch $(OSPLAT)
			{
			case X86 :
				LINKFLAGS on $(_t) +=
					-L$(QTDIR)/lib
					-L/usr/X11R6/lib
					$(LINKFLAGS) $(dev_LINKFLAGS) ;

			case X86_64 :
				LINKFLAGS on $(_t) +=
					-L$(QTDIR)/lib
					-L/usr/X11R6/lib64
					$(LINKFLAGS) $(dev_LINKFLAGS) ;
			}

			if ! $(TYPE_DYNAMIC)
			{
				# These libraries must be enumerated explicitly because our
				# static production Qt libs depend on them.
				QT4LIBLIST +=
					Xrender
					Xrandr
					Xcursor
					fontconfig
					ICE
					SM
					X11
					Xext
					m
					rt
					dl ;
			}

			LINKLIBS on $(_t) +=
				-l$(QT4LIBLIST)
				-pthread
				$(LINKLIBS) $(dev_LINKLIBS) ;

		case MACOSX :
			LINKFLAGS on $(_t) += $(LINKFLAGS)
				# comment out -prebind flag, because Qt is
				# not built prebound
				#-prebind
				-L$(QTDIR)/lib   # look here for normal libs
				-F$(QTDIR)/lib   # ...for structured frameworks too
				# This (dynamic) library is listed here so that it appears
				# before any other objects and specifically before
				# libsupp.a, to avoid symbol name collisions.  libz is
				# needed for the QuickTime framework.
				-lz
				$(dev_LINKFLAGS) ;

			LINKLIBS on $(_t) += $(LINKLIBS)
				# This is already on the global LINKLIBS
				#-framework Carbon
				-framework QuickTime
				-framework OpenGL
				-framework AGL
				-framework AppKit ;

			# If you want to link with Qt4 as frameworks on mac,
			# use -sTYPE=dyn or dyng.  Otherwise you get a static
			# (or unix-style dynamic but non-frameworks) link.
			if $(TYPE_DYNAMIC)
			{
				# This pads the executable header so that
				# we can later change dynamic shared
				# library paths recorded in the output file.
				# (See MacP4VdyldFixup action.)
				LINKFLAGS on $(_t) += -Wl,-headerpad_max_install_names ;

				# Argh!  Mac uses the name "QtAssistant" when it's a
				# framework, instead of "QtAssistantClient"!
				QT4LIBLIST = QtAssistant
				             [ FRemoveAny $(QT4LIBLIST) : QtAssistantClient ] ;

 				for _frmwk in $(QT4LIBLIST)
				{
					LINKLIBS on $(_t) += -framework $(_frmwk) ;
				}
			}
			else
			{
				# These libraries must be enumerated explicitly because our
				# static production Qt libs depend on them.
				QT4LIBLIST +=
					iconv
					ssl
					crypto ;

				LINKLIBS on $(_t) += -l$(QT4LIBLIST) ;
			}
			LINKLIBS on $(_t) += $(dev_LINKLIBS) ;

			if $(_opt) != "console"
			{
				QtMacPackage $(<) ;
			}

		case NT :

			# warn about non-dynamic builds on NT
			if ! $(TYPE_DYNAMIC) && ! $(QTWARNED)
			{
				echo Warning: you really want jam -sTYPE=dyn for QT on NT. ;
				QTWARNED = 1 ;
			}

			# no dos box unless debug
			if $(_opt) = "console"
			{
				LINKFLAGS on $(_t) += $(LINKFLAGS) /subsystem:console ;
			}
			else if ! $(TYPE_DEBUG)
			{
				LINKFLAGS on $(_t) += $(LINKFLAGS) /subsystem:windows ;
			}

			local d = "" ;
			if $(TYPE_DEBUG) { d = d ; }

			LINKLIBS on $(_t) = [ FDirName $(QTDIR) lib qtmain$(d).lib ] ;
			for _lib in $(QT4LIBLIST)
			{
				LINKLIBS on $(_t) += [ FDirName $(QTDIR) lib $(_lib)$(d)4.lib ] ;
			}

			LINKLIBS on $(_t) +=
				advapi32.lib	# for qtree
				user32.lib
				gdi32.lib
				comdlg32.lib
				ole32.lib
				oleaut32.lib
				shell32.lib
				uuid.lib
				imm32.lib
				winmm.lib
				ws2_32.lib
				winspool.lib
				version.lib	;

			if $(TYPE_DEBUG) && $(VLD)
			{
				LINKLIBS on $(_t) += $(VLD)/lib/vld.lib ;
			}
		case * :
		    Exit Don't know how to link QT executables on $(OS). ;
		}
	}

	rule QtConsoleLinkage
	{
		# QtConsoleLinkage exe ; - QtLinkage for a console app on NT

		QtLinkage $(<) : console ;
	}

	rule QtDllLinkage
	{
		# QtLinkage exe ; - linkflags/libs for building with QT

		local QT4LIBLIST ;
		if $(NEED_QT3SUPPORT)
		{
			QT4LIBLIST += Qt3Support ;
		}
		QT4LIBLIST +=
			QtAssistantClient
			QtXml
			QtOpenGL
			QtNetwork
			QtGui
			QtCore ;

		switch $(OS)
		{
		case NT :

			# warn about non-dynamic builds on NT
			if ! $(TYPE_DYNAMIC) && ! $(QTWARNED)
			{
				echo Warning: you really want jam -sTYPE=dyn for QT on NT. ;
				QTWARNED = 1 ;
			}

			LINKFLAGS on $(<) += $(LINKFLAGS) /DLL ;
			echo Warning: you are building a dll  $(LINKFLAGS) ;

			# no dos box unless debug
			if ! $(TYPE_DEBUG)
			{
				LINKFLAGS on $(<) += $(LINKFLAGS) /subsystem:windows ;
			}

			# advertise symbols available
			if $(TYPE_DEBUG) && $(MSVSVER) >= 9
			{
				LINKFLAGS on $(<) += /ASSEMBLYDEBUG ;
			}

			local d = "" ;
			if $(TYPE_DEBUG) { d = d ; }

			LINKLIBS on $(<) = [ FDirName $(QTDIR) lib qtmain$(d).lib ] ;
			for _lib in $(QT4LIBLIST)
			{
				LINKLIBS on $(<) += [ FDirName $(QTDIR) lib $(_lib)$(d)4.lib ] ;
			}

			LINKLIBS on $(<) +=
				advapi32.lib	# for qtree
				user32.lib
				gdi32.lib
				comdlg32.lib
				ole32.lib
				oleaut32.lib
				shell32.lib
				uuid.lib
				imm32.lib
				winmm.lib
				ws2_32.lib
				winspool.lib
				shlwapi.lib
				version.lib	;

			if $(TYPE_DEBUG) && $(VLD)
			{
				echo addding vld ;
				LINKLIBS on $(<) += $(VLD)/lib/vld.lib ;
			}
		case * :
			Exit Don't know how to link QT executables on $(OS). ;
		}
	}

	# Mac special package - make a raw executable into a .app folder
	# This does x things:

	# 1. locates the actual exe in exe.app/Contents/MacOS/exe
	# 2. Creates exe.app/Contents/PkgInfo
	# 3. Creates exe.app/Contents/Info.plist
	# 4. Creates exe.app/Contents/Resources/application.icns

	rule QtMacPackage
	{
	    # QtMacPackage exe ;

	    Depends $(<) : <$(<)>PkgInfo ;
	    Depends $(<) : <$(<)>Info.plist ;
	    Depends $(<) : <$(<)>application.icns ;

	    MakeLocate $(<) :
		[ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents MacOS ] ;
	    MakeLocate <$(<)>PkgInfo :
		[ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents ] ;
	    MakeLocate <$(<)>Info.plist :
		[ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents ] ;
	    MakeLocate <$(<)>application.icns :
		[ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents Resources ] ;

	    MacCreatorCode <$(<)>Info.plist : $(<) ;

	    QtMacPackageInfo <$(<)>PkgInfo ;
	    QMS on <$(<)>PkgInfo = [ MacCreatorCode $(<) ] ;

	    QtMacPlist <$(<)>Info.plist : $(<) ;
	}

	actions QtMacPackageInfo
	{
	    echo "APPL$(QMS)" > $(<)
	}

	rule QtMacIcons
	{
	    File <$(<)>application.icns : $(>) ;
	}

	rule QtMacPlist
	{
	    local osid = $(OS)$(OSVER:E)$(OSPLAT:E) ;

	    Depends files : $(<) ;

	    # Add the standard items to the Info.plist file
	    #
	    QtMacAddPListItem $(>) : CFBundleExecutable         : $(>) ;
	    QtMacAddPListItem $(>) : CFBundlePackageType        : "APPL" ;
	    QtMacAddPListItem $(>) : CFBundleShortVersionString : $(RELEASE:J=.) ;
	    QtMacAddPListItem $(>) : CFBundleVersion            : $(RELEASE:J=.)/$(PATCHLEVEL)$(SPECIAL:E) ;
	    QtMacAddPListItem $(>) : CFBundleGetInfoString      : "$(RELEASE:J=.), Copyright $(SUPPDATE[1]) Perforce Software, Inc." ;
	    QtMacAddPListItem $(>) : CFBundleIconFile           : application.icns ;
	    QtMacAddPListItem $(>) : P4RevString                : "$(>:U)/$(osid[1]:U)/$(RELEASE:J=.)/$(PATCHLEVEL)$(SPECIAL:E) ($(SUPPDATE[1])/$(SUPPDATE[2])/$(SUPPDATE[3]))" ;

	    MODE on $(<) = $(FILEMODE) ;
	    Chmod $(<) ;

	    # This is just for the output hack in the action QtMacPList
	    JOINER_VARIABLE on $(<) = " >> " ;
	}

	# Adds a string item to Info.plist
	# concatenates the XML description to a string which contains the contents
	#
	rule QtMacAddPListItem
	{
	    MAC_PLIST_CONTENTS on <$(<)>Info.plist  += " \"    <key>$(2)</key>\"" ;
	    MAC_PLIST_CONTENTS on <$(<)>Info.plist  += " \"    <string>$(3)</string>\"" ;
	}

	# Writes out an XML file that conforms to the Info.pllist format
	#
	# look at the central line very carefully
	# the whole thing gets expanded into multiple lines because
	# there are no spaces in this line. They are made into multiple
	# permutations of every value in MAC_PLIST_CONTENTS.
	# each value begins with a space (so there is a space after "echo"
	# and each one uses the one value in JOINER_VARIABLE so it can
	# put spaces between current the MAC_PLIST_CONTENTS value, and
	# the value of the file which it will be appended to
	#
	actions QtMacPlist
	{
		echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > $(<)
		echo "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"  >> $(<)
		echo "<plist version=\"1.0\">"  >> $(<)
		echo "<dict>"                   >> $(<)


		echo$(MAC_PLIST_CONTENTS)$(JOINER_VARIABLE)$(<);


		echo "</dict>"                  >> $(<)
		echo "</plist>"                 >> $(<)
	}

	# Library rules

	rule QtHdrRule
	{
		# Our own HdrRule that knows a .ui doesn't itself include
		# a .h, but instead causes the resulting .cpp to do so.
		# What .cpp?  TCPP is set on the .ui by QtFormLibrary,
		# and that's how we know it's this rigged dependency.

		HdrRule $(TCPP:E=$(<)) : $(>) ;
	}

	rule QtFormLibrary
	{
		# QtFormLibrary lib : *.ui ; make .h's and archive .obj's

		# For each x.ui file we generate _3_ files:
		#
		#	x.h (uic x.ui)
		#	tx.cpp (uic x.ui x.h) (temp)
		#	mx.cpp (moc x.h) (temp)
		#
		# The tx.cpp and mx.cpp get compiled into tx.o and mx.o
		# and archived into the library.

		Library $(<) : m$(>:S=.cpp) ;
		Library $(<) : t$(>:S=.cpp) ;

		local i ;

		for i in $(>)
		{
		    local h = $(i:S=.h) ;
		    local ui = [ FGristSourceFiles $(i) ] ;
		    local mcpp = [ FGristSourceFiles m$(i:S=.cpp) ] ;
		    local tcpp = [ FGristSourceFiles t$(i:S=.cpp) ] ;
		    local mobj = $(mcpp:S=$(SUFOBJ)) ;
		    local tobj = $(tcpp:S=$(SUFOBJ)) ;

		    # .ui's can include .h files, though what it actually
		    # means is that the generated tx.cpp includes the .h's,
		    # so we pass the tx.cpp name down to our own QtHdrRule.

		    TCPP on $(ui) = $(tcpp) ;
		    HDRRULE on $(ui) = QtHdrRule ;
		    HDRSCAN on $(ui) = "<include .*>(.*)</include>" ;
		    HDRSEARCH on $(ui) =
			$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;

		    QtUicHdr $(h) : $(ui) ;
		    QtUicCpp $(tcpp) : $(ui) $(h) ;
		    QtMoc $(mcpp) : $(h) ;

		    if ! $(TYPE_DEBUG) { RmTemps $(mobj) : $(mcpp) ; }
		    if ! $(TYPE_DEBUG) { RmTemps $(tobj) : $(tcpp) ; }

		    Includes $(mcpp) : $(h) ;
		    Includes $(tcpp) : $(h) ;
		}
	}

	rule QtMocLibrary
	{
		# QtMocLibrary lib : *.h ; - moc, compile, & archive

		# X.h -> temp mX.cpp -> temp mX.obj -> lib
		# Normal library rule on the generated m*.cpp files

		Library $(<) : m$(>:S=.cpp) ;

		# Make mX.cpp from X.h using moc
		# mX.cpp is a temp

		local h ;

		for h in $(>)
		{
		    local cpp = [ FGristSourceFiles m$(h:S=.cpp) ] ;
		    local obj = $(cpp:S=$(SUFOBJ)) ;
		    local gh = [ FGristFiles $(h) ] ;
		    QtMoc $(cpp) : $(gh) ;
		    if ! $(TYPE_DEBUG) { RmTemps $(obj) : $(cpp) ; }
		}
	}

	# Source file rules

	rule QtImages
	{
		# QtImages x.h : files ; - make a .h from image files

		# Delete and do piecemeal append for line-length limited NT.

		QtEmpty $(<) ;

		QEMBED on $(<) = $(QTUIC) ;
		QtEmbed $(<) : $(>) : -embed $(<:B) ;
	}

	actions QtEmpty
	{
		$(RM) $(<)
	}

	rule QtEmbed
	{
		# QtEmbed x.h : files : flags ; - preprocess with qembed

		NotFile src ;
		Depends src : $(<) ;

		Depends all : $(<) ;
		Depends $(<) : $(>) ;
		Clean clean : $(<) ;

		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		MakeLocate $(<) : $(LOCATE_SOURCE) ;

		QEMBEDFLAGS on $(<) = $(3) ;
	}

	actions piecemeal QtEmbed
	{
		$(QEMBED) $(QEMBEDFLAGS) $(>) >> $(<)
	}

	# Escaping <, >, and " on Unix and NT.

	if $(OS) = NT { Q = ^ ; } else { Q = \\ ; }

	actions QtRStart
	{
		$(RM) $(<)
		echo $(Q)<!DOCTYPE RCC$(Q)>$(Q)<RCC version=$(Q)"1.0$(Q)"$(Q)> >> $(<)
	}

	actions quietly QtRHead
	{
		echo $(Q)<qresource prefix=$(Q)"/$(>)$(Q)"$(Q)> >> $(<)
	}

	actions quietly QtRLine
	{
		echo $(Q)<file alias=$(Q)"$(>:BS)$(Q)"$(Q)>$(>)$(Q)</file$(Q)> >> $(<)
	}

	actions quietly QtRTail
	{
		echo $(Q)</qresource$(Q)> >> $(<)
	}

	actions  QtREnd
	{
		echo $(Q)</RCC$(Q)> >> $(<)
	}

	actions QtRcc
	{
		$(QTRCC) -compress 5 -o $(<) -name $(<:B) $(>)
	}

	rule QtResource
	{
		# QtResource qrc : ModuleName : pngFiles ;

		local qrc = $(1) ;
		local mod = $(2) ;
		local png = [ FGristSourceFiles $(3) ] ;

		# can't put qrc anywhere but local directory
		# because *(&^#$ rcc thinks includes are relative
		# to there, not directory of invocation.

		# MakeLocate $(qrc) : $(LOCATE_SOURCE) ;

		# .qrc goes in the bin
		# .pngs come from the source

		SEARCH on $(png) = $(SEARCH_SOURCE) ;
		Clean clean : $(qrc) ;
		Depends $(qrc) : $(png) ;
		NotFile $(mod) ;

		# Write the .qrc file
		# Note that QtREnd is called by QtResourceCpp

		on $(qrc) if ! $(Started)
		{
			QtRStart $(qrc) ;
			Started on $(qrc) = true ;
		}

		QtRHead $(qrc) : $(mod) ;
		for _i in $(png) { QtRLine $(qrc) : $(_i) ; }
		QtRTail $(qrc) ;
	}

	rule QtResourceCpp
	{
		# QtResourceCpp cpp : qrc ;

		local cpp = [ FGristSourceFiles $(1) ] ;
		local qrc = $(2) ;

		QTRCC    = [ FDirName $(QTDIR) bin rcc ] ;

		MakeLocate $(cpp) : $(LOCATE_SOURCE) ;
		Clean clean : $(cpp) ;
		Depends files : $(cpp) ;
		Depends $(cpp) : $(qrc) ;

		# Write the tail of qrc file
		# Then call rcc to build the cpp file.

		QtREnd $(qrc) ;
		QtRcc $(cpp) : $(qrc) ;

		# we can get rid of the qrc once we have the cpp

		RmTemps $(cpp) : $(qrc) ;
	}

	rule QtMoc
	{
		# QtMoc x.cpp : x.h ; - preprocess with moc

		# Derive a .cpp from .h using Qt's moc

		NotFile src ;
		Depends src : $(<) ;

		Depends all : $(<) ;
		Depends $(<) : $(>) ;
		Clean clean : $(<) ;

		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		MakeLocate $(<) : $(LOCATE_SOURCE) ;
	}

	actions QtMoc
	{
		$(QTMOC) $(>) -o $(<)
	}

	rule QtUicCpp
	{
		# QtUicCpp x.cpp : x.ui x.h ; - preprocess with uic to make .cpp

		NotFile src ;
		Depends src : $(<) ;

		Depends all : $(<) ;
		Depends $(<) : $(>) ;
		Clean clean : $(<) ;

		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		MakeLocate $(<) : $(LOCATE_SOURCE) ;
	}

	# don't include dir name in x.h

	actions QtUicCpp
	{
		$(QTUIC) $(>[1]) -i $(>[2]:D=) -o $(<)
	}

	rule QtUicHdr
	{
		# QtUicHdr x.h : x.ui ; - preprocess with uic to make .h

		NotFile src ;
		Depends src : $(<) ;

		Depends all : $(<) ;
		Depends $(<) : $(>) ;
		Clean clean : $(<) ;

		SEARCH on $(>) = $(SEARCH_SOURCE) ;
		MakeLocate $(<) : $(LOCATE_SOURCE) ;
	}

	actions QtUicHdr
	{
		$(QTUIC) $(>) -o $(<)
	}

	rule QtUnitTest
	{
		# $(1) = component to build unit test for
		#	the component is defined in $(1).h and $(1).cpp
		#   the unit test is defined in t_$(1).h and t_$(1).cpp
		# $(2) = list of other components this test depends on
		# $(3) = list of libraries this test depends on

		local lib = t_$(1) ;

		# Need to build component into differently named object file
		# because Library rule will delete normal object file.
		# Create unique names that don't conflict with the unit test
		# files by adding .ut suffix before extension.

		Object <$(SOURCE_GRIST)>$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>$(1).cpp ;
		QtMoc <$(SOURCE_GRIST)>m$(1).ut.cpp : <$(SOURCE_GRIST)>$(1).h ;
		Object <$(SOURCE_GRIST)>m$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>m$(1).ut.cpp ;
		LibraryFromObjects t_$(1) :
			<$(SOURCE_GRIST)>$(1).ut$(SUFOBJ)
			<$(SOURCE_GRIST)>m$(1).ut$(SUFOBJ) ;

		# Rebuild any depencies for same reason.
		for dep in $(2)
		{
			Object <$(SOURCE_GRIST)>$(dep).$(1).ut$(SUFOBJ) :
				<$(SOURCE_GRIST)>$(dep).cpp ;
			QtMoc <$(SOURCE_GRIST)>m$(dep).$(1).ut.cpp : <$(SOURCE_GRIST)>$(dep).h ;
			Object <$(SOURCE_GRIST)>m$(dep).$(1).ut$(SUFOBJ) :
				<$(SOURCE_GRIST)>m$(dep).$(1).ut.cpp ;
			LibraryFromObjects t_$(1) :
				<$(SOURCE_GRIST)>$(dep).$(1).ut$(SUFOBJ)
				<$(SOURCE_GRIST)>m$(dep).$(1).ut$(SUFOBJ) ;
		}

		# Need to compile unit test too since we're forced to use MainFromObjects.
		# Moc'ed cpp files, and their obj files, end up with mt_ prefix.
		Object <$(SOURCE_GRIST)>t_$(1)$(SUFOBJ) : <$(SOURCE_GRIST)>t_$(1).cpp ;
		QtMoc <$(SOURCE_GRIST)>mt_$(1).cpp : <$(SOURCE_GRIST)>t_$(1).h ;
		Object <$(SOURCE_GRIST)>mt_$(1)$(SUFOBJ) : <$(SOURCE_GRIST)>mt_$(1).cpp ;

		MainFromObjects $(1) :
			<$(SOURCE_GRIST)>mt_$(1)$(SUFOBJ)
			<$(SOURCE_GRIST)>t_$(1)$(SUFOBJ) ;
		LinkLibraries $(1) : $(lib) $(3) ;
		QtConsoleLinkage $(1) ;
	}
	rule P4QtCoreHdrs
	{
		SubDirHdrs $(P4QT) p4api include ;
		SubDirHdrs $(P4QT) core include ;
	}

#################################################
#
# Section 8.  Lua build rules and actions.
#
#################################################

	rule Lua2c
	{
		local _t ;
		_t = [ FGristFiles $(>:S=.lb) ] ;

		LuaCompile $(>) ;
		LOCATE on $(<) = $(SEARCH_SOURCE) ;
		DEPENDS lib : $(<) ;
		DEPENDS $(<) : $(_t) ;
		LuaBin2c $(<) : $(_t) ;
	}

	rule LuaCompile
	{
		local _t _i ;

		for _i in [ FGristFiles $(<:S=.lua) ]
		{
			_t = $(_i:S=.lb) ;
			SEARCH on $(_i) = $(SEARCH_SOURCE) ;
			LOCATE on $(_t) = $(LOCATE_TARGET) ;
			DEPENDS obj : $(_t) ;
			DEPENDS $(_t) : $(_i) ;
			Luac $(_t) : $(_i) ;
		}
	}

	actions LuaBin2c {
		bin2c $(>) > $(<)
	}

	actions Luac {
		luac -s -o $(<) $(>)
	}

#################################################
#
# Section 9.  Per-platform actions.
#
#################################################

if $(NT) && $(MSVCNT)
{
	actions updated together piecemeal Archive {
	    pushd $(<:D)
	    if exist $(<:BS) set _$(<:B)_=$(<:BS)
	    $(AR) /nologo /out:$(<:BS) %_$(<:B)_% $(>:BS)
	    popd
	}

	actions QtEmpty {
	    if exist $(<) $(RM) $(<)
	}

	actions Link bind NEEDLIBS DEFFILE
	{
		$(LINK) $(LINKFLAGS) /out:$(<) /def:$(DEFFILE) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
		if exist $(<).manifest mt -manifest $(<).manifest -outputresource:$(<);2
	}
}

if $(NT)
{
	actions MkTarArchive
	{
		tar cf $(<) -C $(>:P) $(>:BE)$(>:SE)
	}
}

if $(VMS)
{
	actions MkTarArchive
	{
		set default $(<:D)
		vmstar cvdzf $(<:B)$(<:S) [.$(>:B)...]
		set file/prot=(o:rwed) $(<:B)$(<:S)
	}

	actions MkZipArchive
	{
		set default $(<:D)
		zip "-9wrV" $(<:B)$(<:S) $(>:BS=.dir)
	}

	actions MkBckArchive
	{
		set default $(<:D)
		backup [.$(>:B)...] $(<:B)$(<:S)/save
		set file/prot=(o:rwed) $(<:B)$(<:S)
	}
}

# end of Jamrules
