Team Wip branch wip
authortnmurphy@4GBL06592.nokia.com
Mon, 16 Nov 2009 20:39:37 +0000
branchwip
changeset 5 593a8820b912
parent 3 e1eecf4d390d
child 7 f9fd2a994239
Team Wip branch Perforce: 1736581
sbsv2/raptor/bin/sbs_filter.py
sbsv2/raptor/lib/config/arm.xml
sbsv2/raptor/lib/config/locations.xml
sbsv2/raptor/lib/config/variants.xml
sbsv2/raptor/lib/flm/bitmap.flm
sbsv2/raptor/lib/flm/build.flm
sbsv2/raptor/lib/flm/e32abiv2.flm
sbsv2/raptor/lib/flm/gccxml.flm
sbsv2/raptor/lib/flm/msvctools.flm
sbsv2/raptor/lib/flm/resource.flm
sbsv2/raptor/lib/flm/run.mk
sbsv2/raptor/lib/flm/stringtable.flm
sbsv2/raptor/lib/flm/tools2common.flm
sbsv2/raptor/linux-i386/bin/bash
sbsv2/raptor/linux-i386/bin/bashbug
sbsv2/raptor/linux-i386/bin/make
sbsv2/raptor/linux-i386/bin/sh
sbsv2/raptor/linux-i386/bin/unzip
sbsv2/raptor/linux-i386/bin/zip
sbsv2/raptor/python/filter_interface.py
sbsv2/raptor/python/plugins/filter_clean.py
sbsv2/raptor/python/plugins/filter_tagcount.py
sbsv2/raptor/python/raptor.py
sbsv2/raptor/python/raptor_buildplatform.py
sbsv2/raptor/python/raptor_cache.py
sbsv2/raptor/python/raptor_cli.py
sbsv2/raptor/python/raptor_data.py
sbsv2/raptor/python/raptor_make.py
sbsv2/raptor/python/raptor_makefile.py
sbsv2/raptor/python/raptor_meta.py
sbsv2/raptor/python/raptor_version.py
sbsv2/raptor/test/common/raptor_tests.py
sbsv2/raptor/test/config/arm.xml
sbsv2/raptor/test/retirement/metadep.py
sbsv2/raptor/test/smoke_suite/bitmap.py
sbsv2/raptor/test/smoke_suite/clean_readonly.py
sbsv2/raptor/test/smoke_suite/commandline.py
sbsv2/raptor/test/smoke_suite/featurevariants.py
sbsv2/raptor/test/smoke_suite/user_tools.py
sbsv2/raptor/test/unit_suite/raptor_data_unit.py
sbsv2/raptor/test/unit_suite/raptor_make_unit.py
sbsv2/raptor/test/unit_suite/raptor_meta_unit.py
sbsv2/raptor/test/unit_suite/raptor_unit.py
sbsv2/raptor/util/install-windows/raptorinstallerscript.nsi
sbsv2/raptor/util/talon/lock.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/bin/sbs_filter.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Symbian Foundation License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import traceback
+
+# intercept the -h option
+if "-h" in sys.argv or "--help" in sys.argv:
+	print "usage:", sys.argv[0], "[sbs options]"
+	print "  The log data is read from stdin."
+	print "  Type 'sbs -h' for a list of sbs options."
+	sys.exit(0)
+	
+# get the absolute path to this script
+script = os.path.abspath(sys.argv[0])
+
+# add the Raptor python directory to the PYTHONPATH
+sys.path.append(os.path.join(os.path.dirname(script), "..", "python"))
+
+# now we should be able to find the raptor modules
+import raptor
+import pluginbox
+
+# make sure that HOSTPLATFORM is set
+if not "HOSTPLATFORM" in os.environ:
+	sys.stderr.write("HOSTPLATFORM is not set ... try running gethost.sh\n")
+	sys.exit(1)
+	
+if not "HOSTPLATFORM_DIR" in os.environ:
+	sys.stderr.write("HOSTPLATFORM_DIR is not set ... try running gethost.sh\n")
+	sys.exit(1)
+
+# construct a Raptor object from our command-line (less the name of this script)
+the_raptor = raptor.Raptor.CreateCommandlineBuild(sys.argv[1:])
+
+# from Raptor.OpenLog()
+try:
+	# Find all the raptor plugins and put them into a pluginbox.
+	if not the_raptor.systemPlugins.isAbsolute():
+		the_raptor.systemPlugins = the_raptor.home.Append(the_raptor.systemPlugins)
+		
+	pbox = pluginbox.PluginBox(str(the_raptor.systemPlugins))
+	raptor_params = raptor.BuildStats(the_raptor)
+
+	# Open the requested plugins using the pluginbox
+	the_raptor.out.open(raptor_params, the_raptor.filterList.split(','), pbox)
+	
+except Exception, e:
+	sys.stderr.write("filter exception: %s\n" % str(e))
+	traceback.print_ex()
+	sys.exit(1)
+		
+# read stdin a line at a time and pass it to the Raptor object
+line = " "
+while line:
+	line = sys.stdin.readline()
+	the_raptor.out.write(line)
+
+# from Raptor.CloseLog()
+if not the_raptor.out.summary():
+	the_raptor.errorCode = 1
+	
+if not the_raptor.out.close():
+	the_raptor.errorCode = 1
+	
+# return the error code
+sys.exit(the_raptor.errorCode)
+
--- a/sbsv2/raptor/lib/config/arm.xml	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/config/arm.xml	Mon Nov 16 20:39:37 2009 +0000
@@ -119,6 +119,9 @@
 	<!-- GCCE 4.3.3 aliases -->
 	<alias name="armv5_urel_gcce4_3_3" meaning="arm.v5.urel.gcce4_3_3"/>
 	<alias name="armv5_udeb_gcce4_3_3" meaning="arm.v5.udeb.gcce4_3_3"/>
+
+	<alias name="armv5_urel_gcce4_4_1" meaning="arm.v5.urel.gcce4_4_1"/>
+	<alias name="armv5_udeb_gcce4_4_1" meaning="arm.v5.udeb.gcce4_4_1"/>
 	
 	<alias name="armv6_urel" meaning="arm.v6.urel.rvct2_2"/>
 	<alias name="armv6_udeb" meaning="arm.v6.udeb.rvct2_2"/>
--- a/sbsv2/raptor/lib/config/locations.xml	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/config/locations.xml	Mon Nov 16 20:39:37 2009 +0000
@@ -77,6 +77,7 @@
 
 	<var name="default.locations" extends="hostplatform.locations">
 		<env name='EPOCROOT' default='' type='path'/>
+		<env name='SBS_HOME' default='' type='path'/>
 		<!-- Place where intermediate files are built -->
 		<env name='SBS_BUILD_DIR' default='$(EPOCROOT)/epoc32/build' type='path'/>
 
--- a/sbsv2/raptor/lib/config/variants.xml	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/config/variants.xml	Mon Nov 16 20:39:37 2009 +0000
@@ -10,6 +10,7 @@
 	<var name="debug_info">
 		<set name='DEBUG_INFO' value='1'/>
 	</var>
+	
 	<!-- Run this variant to turn on trace compiler -->
 	<var name="tracecompiler">
 		<set name='USE_TRACE_COMPILER' value='1'/>
@@ -17,11 +18,12 @@
 		<env name='SBS_JAVATC' default='$(JAVA_HOME)/bin/java.exe' type='tool' versionCommand='$(SBS_JAVATC) -version' versionResult='version \"1\.[5-9]' host='win*' />
 		<env name='SBS_JAVATC' default='$(JAVA_HOME)/bin/java' type='tool' versionCommand='$(SBS_JAVATC) -version' versionResult='version \"1\.[5-9]' host='lin*' />
 	</var>
+	
+	<!-- Overrides the default debugging format for the ARM targets. -->
+	<var name="dwarf3">
+		<set name="DEBUG_FORMAT" value="$(CC.DWARF3)"/>
+	</var>
 
-    <!-- Overrides the default debugging format for the ARM targets. -->
-    <var name="dwarf3">
-        <set name="DEBUG_FORMAT" value="$(CC.DWARF3)"/>
-    </var>
 	<var name="techview">
 	</var>
 
@@ -33,33 +35,33 @@
 		<set name='SAVESPACE' value='TRUE'/>
 	</var>
 
-  <var name="generate_linkerfeedback">
-   <set name='GENERATELINKERFEEDBACK' value='TRUE'/>
-   </var>
+	<var name="generate_linkerfeedback">
+		<set name='GENERATELINKERFEEDBACK' value='TRUE'/>
+	</var>
 
-   <var name="use_linkerfeedback">
-    <set name='GENERATELINKERFEEDBACK' value='TRUE'/>
-   <set name='LINKERFEEDBACK_STAGE2' value='TRUE'/>
-   </var>
+	<var name="use_linkerfeedback">
+		<set name='GENERATELINKERFEEDBACK' value='TRUE'/>
+		<set name='LINKERFEEDBACK_STAGE2' value='TRUE'/>
+	</var>
 
-   <var name="profilerfeedback">
-	   <set name='USE_PROFILER_FEEDBACK' value='TRUE'/>
-	   <env name='ARM_PROFILER_FILE' default='' type='path'/>
-   </var>
+	<var name="profilerfeedback">
+		<set name='USE_PROFILER_FEEDBACK' value='TRUE'/>
+		<env name='ARM_PROFILER_FILE' default='' type='path'/>
+	</var>
 
-   <var name="ltcg">
-	   <set name='LTCG' value='TRUE'/>
-	   <set name='LTCG_OPTION' value='--ltcg'/>
-   </var>
+	<var name="ltcg">
+		<set name='LTCG' value='TRUE'/>
+		<set name='LTCG_OPTION' value='--ltcg'/>
+	</var>
 
-   <var name="multifile">
-    <set name='MULTIFILE_ENABLED' value='TRUE'/>
-   </var>
+	<var name="multifile">
+		<set name='MULTIFILE_ENABLED' value='TRUE'/>
+	</var>
 
-  <!-- build from clean can skip some processing -->
-  <var name="bfc">
-    <set name='DEPEND_SKIP' value='TRUE'/>
-  </var>
+	<!-- build from clean can skip some processing -->
+	<var name="bfc">
+		<set name='DEPEND_SKIP' value='TRUE'/>
+	</var>
 
 	<!-- SMP variant for Kernel Code -->
 	<var name="smp">
@@ -99,8 +101,8 @@
 		<set name="KERNEL_STATIC_RUNTIME_LIB" value="ksrt3_1.lib"/>
 		<set name="NEED_ENTRYPOINT_LIBRARY" value="" />
 	</var>
-
-	<var name="gcce4_3_3" extends="gcce_base">
+	
+    <var name="gcce4_3_3" extends="gcce_base">
 		<env name="GCCEBIN" type="path" />
 		<env name="GCCEVERSION" default="$(TOOLCHAINVERSION)" />
 		<set name="TOOLCHAINVERSION" value="4.3.3" />
@@ -123,7 +125,12 @@
 		<set name="KERNEL_STATIC_RUNTIME_LIB" value="ksrt3_1.lib"/>
 		<set name="NEED_ENTRYPOINT_LIBRARY" value="" />
 	</var>
-
+	
+	<var name="gcce4_4_1" extends="gcce4_3_3">
+		<set name="TOOLCHAINVERSION" value="4.4.1" />
+		<set name="RUNTIME_LIBS_LIST" value="drtaeabi.dso dfpaeabi.dso"/>
+	</var>
+	
 	<var name="rvct2_2" extends="rvct">
 		<env name="RVCT22BIN" type="path"/>
 		<env name="RVCT22INC" type="path"/>
--- a/sbsv2/raptor/lib/flm/bitmap.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/bitmap.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -60,7 +60,7 @@
 
 BMCONVCMDFILE:=$(OUTPUTPATH)/$(BMTARGET)_bmconvcommands
 RELEASEABLES:=$(BITMAPHEADER) $(BITMAPFILE)
-CLEANTARGETS:=$(BITMAPHEADER) $(BITMAPFILE) $(BMCONVCMDFILE)
+CLEANTARGETS:=$(BMCONVCMDFILE)
 
 # The groupbmpin10 macro allows us to construct a command file, 10 
 # bitmap objects at a time to avoid limits on argument lengths and 
@@ -107,7 +107,6 @@
 	$(GNUCP) $$< $$@ \
 	$(call endrule,bitmapcopy)
 
-CLEANTARGETS:=$(CLEANTARGETS) $(MBMCOPYFILES)
 endef
 
 
@@ -140,8 +139,7 @@
 	$(call startrule,bmpfilecopy,FORCESUCCESS) \
 	$(GNUCP) $(1) $(2) && $(GNUCHMOD) +rw $(2) \
 	$(call endrule,bmpfilecopy)
-
-CLEANTARGETS:=$$(CLEANTARGETS) $(2)
+	
 endif
 
 BMPCOPYFILES:=$$(BMPCOPYFILES) $(2)
@@ -163,8 +161,6 @@
 	@if [ ! -d $(EPOCROOT)/epoc32/localisation/group ]; then $(GNUMKDIR) -p $(EPOCROOT)/epoc32/localisation/group; fi
 	@if [ ! -f $$@ ]; then echo "DATADIR: /$(BMBASENAME)" > $$@ ; fi
 	@echo -e "\n/z$(TARGETPATH)/$(BMTARGET) : $(DEPTHBMP)" >> $$@
-
-CLEANTARGETS:=$$(CLEANTARGETS) $(INFOFILE)
 endef
 
 $(eval $(call bmpInfo))
@@ -172,11 +168,11 @@
 # end of localisation #########################################################
 
 ## Clean up
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS) ,$(CREATABLEPATHS)))
+$(call raptor_clean,$(CLEANTARGETS))
 $(call makepath,$(CREATABLEPATHS))
 $(call makepathfor,$(BITMAPHEADER))
 
 # for the abld -what target
 BMPRELEASEABLES:=$(RELEASEABLES) $(MBMCOPYFILES) $(BMPCOPYFILES) $(INFOFILE)
-$(eval $(call whatmacro,$(BMPRELEASEABLES),WHATBITMAP))
+$(call raptor_release,$(BMPRELEASEABLES),BITMAP)
 
--- a/sbsv2/raptor/lib/flm/build.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/build.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -24,36 +24,31 @@
 
 .PHONY:: PP_EXPORTS
 
+ifneq ($(filter win,$(HOSTPLATFORM)),)
+SBS:=$(subst \,/,$(SBS_HOME)/bin/sbs.bat)
+else
+SBS:=$(SBS_HOME)/bin/sbs
+endif
 
-SBS := $(subst \,/,$(SBS_HOME)/bin/sbs)
 
 define doexports
 PP_EXPORTS::
 	$(call startrule,makefile_generation_exports) \
-	export TALON_DESCRAMBLE=0; \
-	$(SBS) --export-only $(component_list) $(config_list) -f- -m $(SBS_BUILD_DIR)/makefiles_export.mk $(cli_options)  --mo=DESCRAMBLE:=  --mo=TALON_DESCRAMBLE:=0 | $(GNUSED) 's#]I*]>#XXX#' \
+	$(SBS) --pp=slave --toolcheck=off --export-only $(component_list) $(config_list) -f- -m $(MAKEFILE_PATH).exports $(cli_options)  \
 	$(call endrule,makefile_generation_exports)
 
-CLEANTARGETS:=$$(CLEANTARGETS) $(SBS_BUILD_DIR)/makefiles_export.mk
+CLEANTARGETS:=$$(CLEANTARGETS) $(MAKEFILE_PATH).exports 
 endef
 
 # Generate makefiles for particular bldinf
 # $(1) = source target source target......
 define generate_makefiles
 
-$$(info XXX component_list=$(COMPONENT_PATHS) makefile=$(MAKEFILE_PATH))
-
-ifeq ($(NO_BUILD),1)
 ALL:: $(MAKEFILE_PATH)
-else
-include $(MAKEFILE_PATH)
-endif
 
 $(MAKEFILE_PATH): $(COMPONENT_PATHS) | PP_EXPORTS 
 	$(call startrule,makefile_generation) \
-	export TALON_DESCRAMBLE=0; \
-	$(SBS) --toolcheck=off -n $(CLI_OPTIONS) $(component_list) $(config_list) -m $$@ -f- --mo=DESCRAMBLE:= --mo=TALON_DESCRAMBLE:=0  | $(GNUSED) 's#\]\][>]#XXX#' && \
-	$(MAKE) -j 8 -f $$@.resource_deps \
+	$(SBS) --pp=slave --toolcheck=off -n $(CLI_OPTIONS) $(component_list) $(config_list) -m $$@ -f- \
 	$(call endrule,makefile_generation)
 
 CLEANTARGETS:=$$(CLEANTARGETS) $(MAKEFILE_PATH) 
@@ -63,13 +58,15 @@
 # Create config list for commands
 config_list:=$(addprefix -c ,$(CONFIGS))
 component_list:=$(addprefix -b ,$(COMPONENT_PATHS))
-$(info COMFIG_LIST: $(config_list))
+$(info <debug>build.flm: configlist: $(config_list)</debug>)
 
 $(eval $(doexports))
 
 # Create the Makefiles
 $(eval $(call generate_makefiles))
 
+CREATABLEPATHS:=$(CREATABLEPATHS) $(dir $(MAKEFILE_PATH))
+
 $(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS),$(CREATABLEPATHS),))
 $(call makepath,$(CREATABLEPATHS))
 
--- a/sbsv2/raptor/lib/flm/e32abiv2.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/e32abiv2.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -279,9 +279,6 @@
 		$(call startrule,importlibtarget_unfrozen,FORCESUCCESS) \
 		$(GNUCP) $$(call dblquote,$$<) $$(call dblquote,$$@) \
 		$(call endrule,importlibtarget_unfrozen)
-
-       CLEANTARGETS:=$$(CLEANTARGETS) $(IMPORTLIBTARGET_DSO)
-
     endef
 
     define importlibtarget_unfrozen_ver
@@ -289,8 +286,6 @@
 		$(call startrule,importlibversioned_unfrozen,FORCESUCCESS) \
 		$(GNUCP) "$(GENERATED_DSO)" "$$@" \
 		$(call endrule,importlibversioned_unfrozen)
-
-      CLEANTARGETS:=$$(CLEANTARGETS) $(IMPORTLIBTARGET_DSO)
     endef
 
     ifeq ($(EXPLICITVERSION),)
@@ -307,8 +302,6 @@
 	   $(call startrule,importlibtarget,FORCESUCCESS) \
 	   $(GNUCP) "$$<" "$$@" \
 	   $(call endrule,importlibtarget)
-
-          CLEANTARGETS:=$$(CLEANTARGETS) $(IMPORTLIBTARGET_DSO)
       endef
 
       ifeq ($(EXPLICITVERSION),)
@@ -325,8 +318,6 @@
 	 	  --dso=$$(call dblquote,$$@) 				   \
 	 	  --linkas=$(call dblquote,$(LINKASVERSIONED)) \
 	      $(call endrule,importlibversioned)
-
-              CLEANTARGETS:=$$(CLEANTARGETS) $(IMPORTLIBTARGETVERSIONED_DSO)
       endef
       $(eval $(importlibtargetversioned_func))
     endif #  ifneq ($(DEFFILE),)
@@ -335,7 +326,6 @@
 
 # ABIv1 .lib
 ifneq ($(IMPORTLIBTARGETVERSIONED_LIB),) # check that we haven't tried to specify this target already
-  CLEANTARGETS:=$(CLEANTARGETS) $(IMPORTLIBTARGETVERSIONED_LIB) $(IMPORTLIBTARGET_LIB)
 
   define abiv1_generatelib
 
@@ -534,7 +524,7 @@
 endef
 $(eval $(artarget_func))
 
-CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE) $(ARTARGET) $(if $(DUMPBCINFO),$(ARTARGET).elfdump,)
+CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE) $(if $(DUMPBCINFO),$(ARTARGET).elfdump,)
 endif
 
 
@@ -624,9 +614,7 @@
 endef
 $(eval $(linktarget_func))
 
-CLEANTARGETS:=$(CLEANTARGETS) $(LINK_TARGET) $(if $(GENERATELINKERFEEDBACK),$(FEEDBACKFILE)) $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT))
-CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE)
-CLEANTARGETS:=$(CLEANTARGETS) $(MAPFILE)
+CLEANTARGETS:=$(CLEANTARGETS) $(VIAFILE) $(if $(GENERATELINKERFEEDBACK),$(FEEDBACKFILE)) $(if $(MULTIFILE_ENABLED),$(MULTIFILEOBJECT))
 WHATRELEASE:=$(WHATRELEASE) $(MAPFILE)
 
 endif # if TARGETTYPE lib
@@ -1132,7 +1120,6 @@
     PREVIOUSVARIANTTYPE:=$(VARIANTTYPE)
 
     WHATRELEASE:=$(WHATRELEASE) $(ROMFILENAME)
-    CLEANTARGETS:=$(CLEANTARGETS) $(ROMFILENAME)
 endif
 
 # Deal with test code batch files generation.
@@ -1143,7 +1130,6 @@
     BATCHFILE_CREATED_$(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH):=1
     TARGET_CREATED_$(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)_$(TARGET):=1
     WHATRELEASE:=$(WHATRELEASE) $(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)
-    CLEANTARGETS:=$(CLEANTARGETS) $(EPOCROOT)/epoc32/data/z/test/$(MODULE)/$(VARIANTPLATFORM).$(TESTPATH)
 endif
 
 ###################### End of Build ROMFILE target ######################
@@ -1183,10 +1169,10 @@
 $(call makepath,$(CREATABLEPATHS))
 
 ## Clean up
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS) ,$(CREATABLEPATHS),))
+$(call raptor_clean,$(CLEANTARGETS))
 
-# For the abld -what target
-$(eval $(call whatmacro,$(filter-out %.sym,$(WHATRELEASE)),WHATARMV5))
+# For the --what option and the log file
+$(call raptor_release,$(filter-out %.sym,$(WHATRELEASE)))
 
 endif # FEATUREVARIANTNAME=="" or FEATUREVARIANT==1
 
--- a/sbsv2/raptor/lib/flm/gccxml.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/gccxml.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -92,7 +92,7 @@
 TEMPGXPARCHIVE:=$(VARIANTBLDPATH)/$(TARGET)$(BASE_TYPE).gxp
 GXPARCHIVE:=$(VARIANTRELEASEPATH)/$(TARGET)$(BASE_TYPE).gxp
 
-CLEANTARGETS:=$(CLEANTARGETS) $(MMPXMLFILE) $(SRCXMLFILES) $(DEPFILES) $(TEMPGXPARCHIVE) $(GXPARCHIVE)
+CLEANTARGETS:=$(CLEANTARGETS) $(MMPXMLFILE) $(SRCXMLFILES) $(DEPFILES) $(TEMPGXPARCHIVE)
 RELEASABLES:=$(RELEASABLES) $(GXPARCHIVE)
 
 # Deduce whether we should be performing a build with standard CPP characteristics
@@ -252,6 +252,6 @@
 TARGET:: $(RELEASABLES)
 
 # clean up
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS),$(CREATABLEPATHS),))
+$(call raptor_clean,$(CLEANTARGETS))
 $(call makepath, $(CREATABLEPATHS))
 
--- a/sbsv2/raptor/lib/flm/msvctools.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/msvctools.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -28,7 +28,6 @@
 $(call makepath,$(RELEASEPATH))
 $(call makepath,$(BUILDPATH))
 
-CLEANTARGETS:=$(CLEANTARGETS) $(RELEASETARGET)
 RELEASEABLES:=$(RELEASEABLES) $(RELEASETARGET)
 
 GENDEBUGINFO:=$(if $(findstring deb,$(VARIANTTYPE)),1,)
@@ -157,7 +156,6 @@
 
 ifneq ($(INSTALLPATH),)
   INSTALLTARGET:=$(INSTALLPATH)/$(TARGET).$(if $(REQUESTEDTARGETEXT),$(REQUESTEDTARGETEXT),$(TARGETTYPE))
-  CLEANTARGETS:=$(CLEANTARGETS) $(INSTALLTARGET)
   RELEASEABLES:=$(RELEASEABLES) $(INSTALLTARGET)
 
   define msvctoolsinstall
@@ -180,7 +178,7 @@
 ifneq ($(GENDEBUGINFO),)
   BSCFILE:=$(RELEASEPATH)/$(TARGET).bsc
   BSCRESPONSEFILE:=$(BUILDPATH)/$(TARGET).brf
-  CLEANTARGETS:=$(CLEANTARGETS) $(BSCFILE) $(BSCRESPONSEFILE)
+  CLEANTARGETS:=$(CLEANTARGETS) $(BSCRESPONSEFILE)
   RELEASEABLES:=$(RELEASEABLES) $(BSCFILE)
 
   define msvctoolsgenbrowse  
@@ -207,6 +205,6 @@
 endif
 
 # clean up
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS),,))
-# for the abld -what target
-$(eval $(call whatmacro,$(INSTALLTARGET),WHATTOOLS))
+$(call raptor_clean,$(CLEANTARGETS))
+# for the --what option and the log file
+$(call raptor_release,$(INSTALLTARGET))
--- a/sbsv2/raptor/lib/flm/resource.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/resource.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -101,8 +101,6 @@
 	@if [ ! -f $$@ ]; then echo "DATADIR: /$(RSSBASENAME)" > $$@ ; fi
 	@echo -e "\n/z$(TARGETPATH)/$(TARGET_lower).rsc : $(RSSBASENAME).rpp" >> $$@
 
-CLEANTARGETS:=$$(CLEANTARGETS) $(DESTRPP) $(INFOFILE)
-
 endif
 endef
 
@@ -174,7 +172,6 @@
 
    ifeq ($(TARGET_$(call sanitise,$2)),)
            TARGET_$(call sanitise,$2):=1
-        CLEANTARGETS:=$$(CLEANTARGETS) $2
 
         RESOURCE:: $2
         ## perform additional copies of binaries
@@ -201,7 +198,6 @@
 
         ifeq ($(TARGET_$(call sanitise,$1)),)
                 TARGET_$(call sanitise,$1):=1
-            CLEANTARGETS:=$$(CLEANTARGETS) $(1)
 
             $(if $(FLMDEBUG),$(info generateresource: $(1) from $(2) LANG:$(3)),)
 
@@ -236,7 +232,6 @@
 
         ifeq ($(TARGET_$(call sanitise,$1)),)
                 TARGET_$(call sanitise,$1):=1
-                CLEANTARGETS:= $$(CLEANTARGETS) $(1)
                 $(if $(FLMDEBUG),$(info resourceheader: $(1) from $(2) LANG:$(3)))
 
                 RESOURCE:: $(1)
@@ -282,7 +277,6 @@
 ifneq ($(RFIFILE),)
   RESOURCE:: $(RFIFILE)
   RELEASABLES:=$(RELEASABLES) $(RFIFILE)
-  CLEANTARGETS:=$(CLEANTARGETS) $(RFIFILE)
   CREATABLEPATHS:=$(CREATABLEPATHS) $(dir $(RFIFILE))
 
   RPPFILES:=$(foreach L,$(LANGUAGES:SC=sc),$(INTERBASE)_$(L).rpp)
@@ -291,11 +285,11 @@
 
 
 ## Clean up
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS),$(CREATABLEPATHS),))
+$(call raptor_clean,$(CLEANTARGETS))
 # make the output directories while reading makefile - some build engines prefer this
 $(call makepath,$(CREATABLEPATHS))
 
-# for the abld -what target
+# for the --what option and the log file
 RELEASABLES:=$(RELEASABLES) $(DESTRPP) $(INFOFILE)
-$(eval $(call whatmacro,$(RELEASABLES),WHATRESOURCES))
+$(call raptor_release,$(RELEASABLES),RESOURCE)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/lib/flm/run.mk	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,39 @@
+.PHONY:: ALL
+ALL:: # Default target
+
+HOSTPLATFORM:=win 32
+HOSTPLATFORM_DIR:=win32
+OSTYPE:=cygwin
+FLMHOME:=E:/wip2/lib/flm
+SHELL:=E:/wip2/win32/cygwin/bin/sh.exe
+
+
+USE_TALON:=
+
+
+
+include E:/wip2/lib/flm/globals.mk
+
+# dynamic default targets
+
+# call E:/wip2/lib/flm/config/default.flm
+SBS_SPECIFICATION:=Symbian.config.default
+SBS_CONFIGURATION:=armv5_urel
+
+EPOCROOT:=E:/wip2/test/epocroot
+ELF2E32:=E:/wip2/test/epocroot/epoc32/tools/elf2e32.exe
+WHATLOG:=
+include E:/wip2/lib/flm/config/default.flm
+
+
+component_paths:=$(SBS_HOME)/test/smoke_suite/test_resources/simple/bld.inf|c:/make_test/a.mk \
+$(SBS_HOME)/test/smoke_suite/test_resources/simple_dll/bld.inf|c:/make_test/b.mk \
+$(SBS_HOME)/test/smoke_suite/test_resources/simple/always_build_as_arm_bld.inf|c:/make_test/c.mk \
+$(SBS_HOME)/test/smoke_suite/test_resources/simple/debuggable_bld.inf|c:/make_test/d.mk \
+$(SBS_HOME)/test/smoke_suite/test_resources/simple_export/bld.inf|c:/make_test/e.mk
+
+configs:=armv5 armv7
+
+cli_options:=-d
+
+include build.flm
--- a/sbsv2/raptor/lib/flm/stringtable.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/stringtable.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -33,9 +33,7 @@
 
 EXPORT::
 
-
 CLEANTARGETS:=
-CLEANEXPORTS:=
 RELEASEEXPORTS:=
 CREATABLEPATHS:=$(OUTPUTPATH) $(EXPORTPATH)
 
@@ -60,7 +58,6 @@
 	$(GNUCP) '$(STRINGTABLEHEADER)' '$$@'  \
 	$(call endrule,exportstringtableheader) 
 
-CLEANEXPORTS:=$(EXPORTEDSTRINGTABLEHEADER)
 RELEASEEXPORTS:=$(EXPORTEDSTRINGTABLEHEADER)
 endef
 
@@ -83,24 +80,9 @@
 $(eval $(genstringtable))
 
 
-## Clean up and log releasables (using eval to avoid target specific variables)
-$(eval $(call GenerateStandardCleanTarget,$(CLEANTARGETS),$(CREATABLEPATHS),))
-$(eval $(call GenerateStandardCleanTarget,$(CLEANEXPORTS),,CLEANEXPORT))
+## Clean up and log releasables
+$(call raptor_clean,$(CLEANTARGETS))
 # make the output directories while reading makefile - some build engines prefer this
 $(call makepath,$(CREATABLEPATHS))
-$(eval $(call whatmacro,$(RELEASEEXPORTS),WHATSTRINGTABLE))
+$(call raptor_release,$(RELEASEEXPORTS),STRINGTABLE)
 
-########################
-# SBSv1 example:
-########################
-# GENERATED_FILES= \
-#         $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.cpp \
-#         $(EPOCROOT)epoc32\include\WspParamConstants.h
-# 
-# $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.cpp : ..\strings\WspParamConstants.st
-#         perl -S ecopyfile.pl ..\strings\WspParamConstants.st $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.st
-#         perl $(EPOCROOT)epoc32\tools\stringtable.pl $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.st
-# 
-# $(EPOCROOT)epoc32\include\WspParamConstants.h : $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.cpp
-#         perl -S ecopyfile.pl $(EPOCROOT)epoc32\build\generated\http\WspParamConstants.h $(EPOCROOT)epoc32\include\WspParamConstants.h
-# 
--- a/sbsv2/raptor/lib/flm/tools2common.flm	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/lib/flm/tools2common.flm	Mon Nov 16 20:39:37 2009 +0000
@@ -99,9 +99,9 @@
 # make the output directories while reading makefile - some build engines prefer this
 $(call makepath,$(CREATABLEPATHS))
 
-## Clean up (using eval to avoid target specific variables)
-$(eval $(call GenerateStandardCleanTarget,$(TARGETS) $(OBJECTFILES),$(CREATABLEPATHS),))
-## WHAT target
-$(eval $(call whatmacro,$(RELEASEABLES),WHATTOOLS2))
+## Clean up
+$(call raptor_clean,$(CLEANTARGETS) $(OBJECTFILES))
+## for the --what option and the log file
+$(call raptor_release,$(RELEASEABLES))
 
 ## The End
Binary file sbsv2/raptor/linux-i386/bin/bash has changed
--- a/sbsv2/raptor/linux-i386/bin/bashbug	Mon Nov 16 09:46:46 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-#!/bin/sh -
-#
-# bashbug - create a bug report and mail it to the bug address
-#
-# The bug address depends on the release status of the shell.  Versions
-# with status `devel', `alpha', `beta', or `rc' mail bug reports to
-# chet@cwru.edu and, optionally, to bash-testers@cwru.edu.
-# Other versions send mail to bug-bash@gnu.org.
-#
-# Copyright (C) 1996-2004 Free Software Foundation, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
-
-#
-# configuration section:
-#	these variables are filled in by the make target in Makefile
-#
-MACHINE="i686"
-OS="linux-gnu"
-CC="gcc"
-CFLAGS=" -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/opt/symbian/linux-i386/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -O2 -mtune=i686 -s"
-RELEASE="3.2"
-PATCHLEVEL="39"
-RELSTATUS="release"
-MACHTYPE="i686-pc-linux-gnu"
-
-PATH=/bin:/usr/bin:/usr/local/bin:$PATH
-export PATH
-
-# Check if TMPDIR is set, default to /tmp
-: ${TMPDIR:=/tmp}
-
-#Securely create a temporary directory for the temporary files
-TEMPDIR=$TMPDIR/bbug.$$
-(umask 077 && mkdir $TEMPDIR) || {
-	echo "$0: could not create temporary directory" >&2
-	exit 1
-}
-
-TEMPFILE1=$TEMPDIR/bbug1
-TEMPFILE2=$TEMPDIR/bbug2
-        
-USAGE="Usage: $0 [--help] [--version] [bug-report-email-address]"
-VERSTR="GNU bashbug, version ${RELEASE}.${PATCHLEVEL}-${RELSTATUS}"
-
-do_help= do_version=
-
-while [ $# -gt 0 ]; do
-	case "$1" in
-	--help)		shift ; do_help=y ;;
-	--version)	shift ; do_version=y ;;
-	--)		shift ; break ;;
-	-*)		echo "bashbug: ${1}: invalid option" >&2
-			echo "$USAGE" >& 2
-			exit 2 ;;
-	*)		break ;;
-	esac
-done
-
-if [ -n "$do_version" ]; then
-	echo "${VERSTR}"
-	exit 0
-fi
-
-if [ -n "$do_help" ]; then
-	echo "${VERSTR}"
-	echo "${USAGE}"
-	echo
-	cat << HERE_EOF
-Bashbug is used to send mail to the Bash maintainers
-for when Bash doesn't behave like you'd like, or expect.
-
-Bashbug will start up your editor (as defined by the shell's
-EDITOR environment variable) with a preformatted bug report
-template for you to fill in. The report will be mailed to the
-bash maintainers by default. See the manual for details.
-
-If you invoke bashbug by accident, just quit your editor without
-saving any changes to the template, and no bug report will be sent.
-HERE_EOF
-	exit 0
-fi
-
-# Figure out how to echo a string without a trailing newline
-N=`echo 'hi there\c'`
-case "$N" in
-*c)	n=-n c= ;;
-*)	n= c='\c' ;;
-esac
-
-BASHTESTERS="bash-testers@cwru.edu"
-
-case "$RELSTATUS" in
-alpha*|beta*|devel*|rc*)	BUGBASH=chet@cwru.edu ;;
-*)				BUGBASH=bug-bash@gnu.org ;;
-esac
-
-case "$RELSTATUS" in
-alpha*|beta*|devel*|rc*)
-		echo "$0: This is a testing release.  Would you like your bug report"
-		echo "$0: to be sent to the bash-testers mailing list?"
-		echo $n "$0: Send to bash-testers? $c"
-		read ans
-		case "$ans" in
-		y*|Y*)	BUGBASH="${BUGBASH},${BASHTESTERS}" ;;
-		esac ;;
-esac
-
-BUGADDR="${1-$BUGBASH}"
-
-if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
-	if [ -x /usr/bin/editor ]; then
-		DEFEDITOR=editor
-	elif [ -x /usr/local/bin/ce ]; then
-		DEFEDITOR=ce
-	elif [ -x /usr/local/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/contrib/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/bin/emacs ]; then
-		DEFEDITOR=emacs
-	elif [ -x /usr/bin/xemacs ]; then
-		DEFEDITOR=xemacs
-	elif [ -x /usr/contrib/bin/jove ]; then
-		DEFEDITOR=jove
-	elif [ -x /usr/local/bin/jove ]; then
-		DEFEDITOR=jove
-	elif [ -x /usr/bin/vi ]; then
-		DEFEDITOR=vi
-	else
-		echo "$0: No default editor found: attempting to use vi" >&2
-		DEFEDITOR=vi
-	fi
-fi
-
-
-: ${EDITOR=$DEFEDITOR}
-
-: ${USER=${LOGNAME-`whoami`}}
-
-trap 'rm -rf "$TEMPDIR"; exit 1' 1 2 3 13 15
-trap 'rm -rf "$TEMPDIR"' 0
-
-UN=
-if (uname) >/dev/null 2>&1; then
-	UN=`uname -a`
-fi
-
-if [ -f /usr/lib/sendmail ] ; then
-	RMAIL="/usr/lib/sendmail"
-	SMARGS="-i -t"
-elif [ -f /usr/sbin/sendmail ] ; then
-	RMAIL="/usr/sbin/sendmail"
-	SMARGS="-i -t"
-else
-	RMAIL=rmail
-	SMARGS="$BUGADDR"
-fi
-
-INITIAL_SUBJECT='[50 character or so descriptive subject here (for reference)]'
-
-cat > "$TEMPFILE1" <<EOF
-From: ${USER}
-To: ${BUGADDR}
-Subject: ${INITIAL_SUBJECT}
-
-Configuration Information [Automatically generated, do not change]:
-Machine: $MACHINE
-OS: $OS
-Compiler: $CC
-Compilation CFLAGS: $CFLAGS
-uname output: $UN
-Machine Type: $MACHTYPE
-
-Bash Version: $RELEASE
-Patch Level: $PATCHLEVEL
-Release Status: $RELSTATUS
-
-Description:
-	[Detailed description of the problem, suggestion, or complaint.]
-
-Repeat-By:
-	[Describe the sequence of events that causes the problem
-	to occur.]
-
-Fix:
-	[Description of how to fix the problem.  If you don't know a
-	fix for the problem, don't include this section.]
-EOF
-
-cp "$TEMPFILE1" "$TEMPFILE2"
-chmod u+w "$TEMPFILE1"
-
-trap '' 2		# ignore interrupts while in editor
-
-edstat=1
-while [ $edstat -ne 0 ]; do
-	$EDITOR "$TEMPFILE1"
-	edstat=$?
-
-	if [ $edstat -ne 0 ]; then
-		echo "$0: editor \`$EDITOR' exited with nonzero status."
-		echo "$0: Perhaps it was interrupted."
-		echo "$0: Type \`y' to give up, and lose your bug report;"
-		echo "$0: type \`n' to re-enter the editor."
-		echo $n "$0: Do you want to give up? $c"
-
-		read ans
-		case "$ans" in
-		[Yy]*) exit 1 ;;
-		esac
-
-		continue
-	fi
-
-	# find the subject from the temp file and see if it's been changed
-	CURR_SUB=`grep '^Subject: ' "$TEMPFILE1" | sed 's|^Subject:[ 	]*||' | sed 1q`
-
-	case "$CURR_SUB" in
-	"${INITIAL_SUBJECT}")
-		echo
-		echo "$0: You have not changed the subject from the default."
-		echo "$0: Please use a more descriptive subject header."
-		echo "$0: Type \`y' to give up, and lose your bug report;"
-		echo "$0: type \`n' to re-enter the editor."
-		echo $n "$0: Do you want to give up? $c"
-
-		read ans
-		case "$ans" in
-		[Yy]*) exit 1 ;;
-		esac
-
-		echo "$0:  The editor will be restarted in five seconds."
-		sleep 5
-		edstat=1
-		;;
-	esac
-
-done
-
-trap 'rm -rf "$TEMPDIR"; exit 1' 2	# restore trap on SIGINT
-
-if cmp -s "$TEMPFILE1" "$TEMPFILE2"
-then
-	echo "File not changed, no bug report submitted."
-	exit
-fi
-
-echo $n "Send bug report? [y/n] $c"
-read ans
-case "$ans" in
-[Nn]*)	exit 0 ;;
-esac
-
-${RMAIL} $SMARGS < "$TEMPFILE1" || {
-	cat "$TEMPFILE1" >> $HOME/dead.bashbug
-	echo "$0: mail failed: report saved in $HOME/dead.bashbug" >&2
-}
-
-exit 0
Binary file sbsv2/raptor/linux-i386/bin/make has changed
Binary file sbsv2/raptor/linux-i386/bin/sh has changed
Binary file sbsv2/raptor/linux-i386/bin/unzip has changed
Binary file sbsv2/raptor/linux-i386/bin/zip has changed
--- a/sbsv2/raptor/python/filter_interface.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/filter_interface.py	Mon Nov 16 20:39:37 2009 +0000
@@ -18,7 +18,7 @@
 
 class Filter(object):
 	
-	def open(self, raptor):
+	def open(self, params):
 		return False
 	
 	def write(self, text):
@@ -32,3 +32,87 @@
 	
 	def formatError(self, message):
 		return "sbs: error: " + message + "\n"
+		
+
+import sys
+import xml.sax
+
+class FilterSAX(Filter, xml.sax.handler.ContentHandler, xml.sax.handler.ErrorHandler):
+	"base class for filters using a SAX parser"
+	
+	# define these methods in your subclass
+	
+	def startDocument(self):
+		"called once before any elements are seen"
+		pass
+		
+	def startElement(self, name, attributes):
+		"called on the opening of any element"
+		pass
+	
+	def characters(self, char):
+		"called one or more times with body text from an element"
+		pass
+		
+	def endElement(self, name):
+		"called on the closing of any element"
+		pass
+	
+	def endDocument(self):
+		"called once when all elements are closed"
+		pass
+
+	def error(self, exception):
+		"the parse found an error which is (possibly) recoverable"
+		pass
+		
+	def fatalError(self, exception):
+		"the parser thinks an error occurred which should stop everything"
+		pass
+		
+	def warning(self, exception):
+		"the parser found something to complain about that might not matter"
+		pass
+		
+	# these methods are from the Filter base class
+	
+	def open(self, params):
+		"initialise"
+		
+		self.params = params
+		self.ok = True
+		try:
+			self.parser = xml.sax.make_parser(['xml.sax.expatreader'])
+			self.parser.setContentHandler(self)
+			self.parser.setErrorHandler(self)
+			
+		except Exception, ex:
+			sys.stderr.write(self.formatError(str(ex)))
+			self.ok = False
+		
+		return self.ok
+	
+		
+	def write(self, text):
+		"process some log text"
+		try:
+			self.parser.feed(text)
+		except Exception, ex:
+			sys.stderr.write(self.formatError(str(ex)))
+			self.ok = False
+				
+		return self.ok
+	
+
+	def close(self):
+		"finish off"
+		try:
+			self.parser.close()
+		except Exception, ex:
+			sys.stderr.write(self.formatError(str(ex)))
+			self.ok = False
+			
+		return self.ok
+	
+
+# the end
--- a/sbsv2/raptor/python/plugins/filter_clean.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/plugins/filter_clean.py	Mon Nov 16 20:39:37 2009 +0000
@@ -51,17 +51,23 @@
 		
 			if self.removeTargets:
 				if line.startswith("<file>"):
-					self.doFile(line)
-				elif line.startswith("<dir>"):
-					self.doDirectory(line)
+					self.doFile(line, "file")
+				elif line.startswith("<build>"):
+					self.doFile(line, "build")
+				elif line.startswith("<resource>"):
+					self.doFile(line, "resource")
+				elif line.startswith("<bitmap>"):
+					self.doFile(line, "bitmap")
+				elif line.startswith("<stringtable>"):
+					self.doFile(line, "stringtable")
 						
 			if self.removeExports:
 				if line.startswith("<export "):
 					self.doExport(line)
 				elif line.startswith("<member>"):
-					self.doMember(line)
+					self.doFile(line, "member")
 				elif line.startswith("<zipmarker>"):
-					self.doZipMarker(line)
+					self.doFile(line, "zipmarker")
 				
 		return self.ok
 	
@@ -81,9 +87,10 @@
 				
 				if os.path.isfile(path):
 					self.removeFile(path)
-					
-				elif os.path.isdir(path):
-					dirs.add(path)
+				
+				directory = os.path.dirname(path)
+				if os.path.isdir(directory):
+					dirs.add(directory)
 					
 			self.tmp.close()	# this also deletes the temporary file
 		except:
@@ -123,47 +130,20 @@
 			self.ok = False
 	
 			
-	def doFile(self, line):
-		"remove filenames in <file> tags immediately (not .d or .dep)."
-		filename = line[6:-7]                # line is "<file>filename</file>
-		filename = filename.strip("\"\'")    # some names are quoted
+	def doFile(self, line, tagname):
+		"deal with <tagname>X</tagname>"
 		
-		# dependency files must be deleted at the end,
-		# everything else can be deleted straight away.
-		if filename.endswith(".d") or filename.endswith(".dep"):
-			self.saveItem(filename)
-		else:
-			if os.path.isfile(filename):
-				self.removeFile(filename)
-
+		first = len(tagname) + 2	# line is "<tagname>filename</tagname>
+		last = -(first + 1)
+		filename = line[first:last]                
+		filename = filename.strip("\"\'")    # some names are quoted
+		self.saveItem(filename)
+				
 
-	def doDirectory(self, line):
-		"save directories in <dir> tags for the end."
-		# assuming <dir>X</dir>
-		dirname = line[5:-6]
-		self.saveItem(dirname.strip("\"\'"))
-		
-		
 	def doExport(self, line):
-		"save exported files in <export> tags for the end."
-		# assuming <export destination='X' source='Y' />
+		"deal with <export destination='X' source='Y'/>"
 		filename = line[21:line.find("'", 21)]
 		self.saveItem(filename)
-		
-		
-	def doMember(self, line):
-		"save zip exports in <member> tags for the end."
-		# assuming <member>X</member>
-		filename = line[8:-9]
-		self.saveItem(filename)
-		
-		
-	def doZipMarker(self, line):
-		"Remove file in <zipmarker> tags"
-		# assuming <zipmarker>X</zipmarker>
-		filename = line[11:-12]
-		if os.path.isfile(filename):
-			self.removeFile(filename)
 
 
 # the end				
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/python/plugins/filter_tagcount.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+# Example of a Filter class using the SAX parser base class
+#
+
+import filter_interface
+
+class FilterTagCounter(filter_interface.FilterSAX):
+	
+	def startDocument(self):
+		# for each element name count the number of occurences
+		# and the amount of body text contained.
+		self.names = []
+		self.count = {}
+		self.errors = 0
+		self.fatals = 0
+		self.warns = 0
+		
+	def startElement(self, name, attributes):
+		if name == "buildlog":
+			# print out the attributes of the "top" element
+			print "version:"
+			for a,v in attributes.items():
+				print a, "=", v
+		
+		# push name onto the stack of names and increment the count
+		self.names.append(name)
+		if name in self.count:
+			self.count[name][0] += 1
+		else:
+			self.count[name] = [1, 0]    # occurs, characters	
+	
+	def characters(self, char):
+		# these are for the current element
+		current = self.names[-1]
+		self.count[current][1] += len(char)
+		
+	def endElement(self, name):
+		# pop the name off the stack
+		self.names.pop()
+	
+	def endDocument(self):
+		# report
+		print "\nsummary:"
+		for name,nos in sorted(self.count.items()):
+			print name, nos[0], nos[1]
+			
+		print "\nparsing:"
+		print "errors =", self.errors
+		print "fatals =", self.fatals
+		print "warnings =", self.warns
+	
+	def error(self, exception):
+		self.errors += 1
+		
+	def fatalError(self, exception):
+		self.fatals += 1
+		
+	def warning(self, exception):
+		self.warns += 1
+	
+# the end
--- a/sbsv2/raptor/python/raptor.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor.py	Mon Nov 16 20:39:37 2009 +0000
@@ -32,6 +32,7 @@
 import raptor_cli
 import raptor_data
 import raptor_make
+import raptor_makefile
 import raptor_meta
 import raptor_utilities
 import raptor_version
@@ -54,8 +55,9 @@
 hostplatform_dir = os.environ["HOSTPLATFORM_DIR"]
 
 # defaults can use EPOCROOT
+
 if "EPOCROOT" in os.environ:
-	epocroot = os.environ["EPOCROOT"].replace("\\","/")
+        epocroot = os.environ["EPOCROOT"].replace("\\","/")
 else:
 	if 'linux' in hostplatform:
 		epocroot=os.environ['HOME'] + os.sep + "epocroot"
@@ -70,7 +72,6 @@
 	sbs_build_dir = (epocroot + "/epoc32/build").replace("//","/")
 
 
-
 # only use default XML from the epoc32 tree if it exists
 defaultSystemConfig = "lib/config"
 epoc32UserConfigDir = generic_path.Join(epocroot, "epoc32/sbs_config")
@@ -105,75 +106,74 @@
 		}
 
 
-class ComponentGroup(object):
-	""" 	Some components that should be built togther 
-		e.g. a Layer in the system definition. 
-	""" 
-	def __init__(self, name, componentlist=[]):
-		self.components = componentlist
-		self.name = name
+
+class ModelNode(object):
+	""" Represents any node in a a tree of build information
+	    e.g. a tree of bld.infs, mmps and finally things like resource blocks and string table blocks.
+	    This is before they are produced into "build" specs.
+	"""
+
+	def __init__(self, id, parent = None):
+		self.id = id
+		self.type = type
+		self.specs = []
+		self.deps = []
+		self.children = set() 
+		self.unfurled = False
+		self.parent = parent
+
+	# Allow one to make a set
+	def __hash__(self):
+		return hash(self.id)
+
+	def __cmp__(self,other):
+		return cmp(self.id, other)
 
 	def __iter__(self):
-		return iter(self.components)
+		return iter(self.children)
 
 	def __getitem__(self,x):
 		if isinstance(x, slice):
-			return self.components[x.start:x.stop]
-		return self.components[x]
+			return self.children[x.start:x.stop]
+		return self.children[x]
 
 	def __setitem__(self,k, v):
-		self.components[k] = v
+		self.children[k] = v
 
 	def __len__(self):
-		return len(self.components)
+		return len(self.children)
 
-	def extend(self, c):
-		self.components.extend(c)
-	
-	def append(self, c):
-		self.components.append(c)
+	def add(self, item):
+		return self.children.add(item)
+
+	def isunfurled(self, c):
+		return self.unfurled == False
 
-	def GenerateSpecs(self, genericspecs, configs):
-		"""Return a build spec hierarchy for a ComponentGroup. This involves parsing the component MetaData (bld.infs, mmps). 
-		Takes a raptor object as a parameter (build), together with a list of Configurations.
+	def unfurl(self, build):
+		"""Find any children of this node by processing it, produces specs"""
+		pass
 
-		Returns a tuple consisting of a list of specification objects and a list of dependency files
-		that relate to these specs.
-		"""
-
-		self.specs = []
-		self.specs.extend(genericspecs)
-		self.configs = configs
-		self.dependencies = set()
+	def unfurl_all(self, build):
+		"""Unfurl self and all children - preparatory e.g for realisation"""
+		if not self.unfurled:
+			self.unfurl(build)
 
-		metaReader = None
-		if len (self.components):
-			try:
-				# create a MetaReader that is aware of the list of
-				# configurations that we are trying to build.
-				metaReader = raptor_meta.MetaReader(build, configs)
+		self.realise_exports(build) # permit communication of dependencies between children
 
-				# convert the list of bld.inf files into a specification
-				# hierarchy suitable for all the configurations we are using.
-				self.specs.extend(metaReader.ReadBldInfFiles(self.components,build.doExportOnly))
-
-			except raptor_meta.MetaDataError, e:
-				log.Error(e.Text)
+		for c in self.children:
+			c.unfurl_all(build)
+		
 
-		log.Info("Buildable specification group '%s'", name)
-		build.AttachSpecs(self.specs)
-
-		# Get a unique list of the dependency files that were created
-		if metaReader:
-			for c in metaReader.BuildPlatforms:
-				self.dependencies.update(c["METADEPS"])
-
-
-	def CreateMakefile(self, makefilename_base, engine, named = False):
-		if len(self.specs) <= 0:
-			return None
-
-		if named:
+	def realise_exports(self, build):
+		"""Do the things that are needed such that we can fully unfurl all 
+		   sibling nodes.  i.e. this step is here to "take care" of the dependencies
+		   between siblings.  
+		"""
+		pass
+	
+	def realise_makefile(self, build, specs):
+		makefilename_base = build.topMakefile
+		if self.name is not None:
 			makefile = generic_path.Path(str(makefilename_base) + "_" + raptor_utilities.sanitise(self.name))
 		else:
 			makefile = generic_path.Path(str(makefilename_base))
@@ -181,15 +181,117 @@
 		# insert the start time into the Makefile name?
 		makefile.path = makefile.path.replace("%TIME", build.timestring)
 
-		engine.Write(makefile, self.specs, self.configs)
+		makefileset = build.maker.Write(makefile, specs, build.buildUnitsToBuild)
+
+		return makefileset
+		
+
+	def realise(self, build):
+		"""Give the spec trees to the make engine and actually 
+		"build" the product represented by this model node"""	
+		# Must ensure that all children are unfurled at this point
+		self.unfurl_all(build)
+
+		sp = self.specs	
+
+		build.AssertBuildOK()
+
+		m = self.realise_makefile(build, sp)
+
+		return build.Make(m)
+
 
-		return makefile
+class Project(ModelNode):
+	"""A project or, in symbian-speak, an MMP
+	"""
+	def __init__(self, filename, parent = None):
+		super(Project,self).__init__(filename, parent = parent)
+		# Assume that components are specified in mmp files for now
+		# One day that tyranny might end.
+		self.mmp_name = str(generic_path.Path.Absolute(filename))
+		self.id = self.mmp_name
+		self.unfurled = False
+
+	def makefile(self, makefilename_base, engine, named = False):
+		"""Makefiles for individual mmps not feasible at the moment"""
+		pass # Cannot, currently, "unfurl an mmp" directly but do want 
+		     # to be able to simulate the overall recursive unfurling of a build.
+
+class Component(ModelNode):
+	"""A group of projects or, in symbian-speak, a bld.inf.
+	"""
+	def __init__(self, filename):
+		super(Component,self).__init__(filename)
+		# Assume that components are specified in bld.inf files for now
+		# One day that tyranny might end.
+		self.bldinf = None # Slot for a bldinf object if we spot one later
+		self.bldinf_filename = generic_path.Path.Absolute(filename)
+
+		self.id = str(self.bldinf_filename)
+		self.exportspecs = []
+		self.depfiles = []
+		self.unfurled = False # We can parse this
+
+	def AddMMP(self, filename):
+		self.children.add(Project(filename))
 
 
-	def GenerateMetadataSpecs(self, configs):
+class Layer(ModelNode):
+	""" 	Some components that should be built togther 
+		e.g. a Layer in the system definition. 
+	""" 
+	def __init__(self, name, componentlist=[]):
+		super(Layer,self).__init__(name)
+		self.name = name
+
+		for c in componentlist:
+			self.children.add(Component(c))
+
+	def unfurl(self, build):
+		"""Discover the children of this layer. This involves parsing the component MetaData (bld.infs, mmps). 
+		Takes a raptor object as a parameter (build), together with a list of Configurations.
+
+		We currently have parsers that work on collections of components/bld.infs and that cannot
+		parse at a "finer" level.  So one can't 'unfurl' an mmp at the moment.  
+
+		Returns True if the object was successfully unfurled.
+		"""
+
+		# setup all our components
+		for c in self.children:
+			c.specs = []
+
+		self.configs = build.buildUnitsToBuild
+
+
+		metaReader = None
+		if len (self.children):
+			try:
+				# create a MetaReader that is aware of the list of
+				# configurations that we are trying to build.
+				metaReader = raptor_meta.MetaReader(build, build.buildUnitsToBuild)
+
+				# convert the list of bld.inf files into a specification
+				# hierarchy suitable for all the configurations we are using.
+				self.specs = list(build.generic_specs)
+				self.specs.extend(metaReader.ReadBldInfFiles(self.children, build.doExportOnly))
+
+			except raptor_meta.MetaDataError, e:
+				build.Error(e.Text)
+
+		self.unfurled = True
+
+
+	def meta_realise(self, build):
+		"""Generate specs that can be used to "take care of" finding out more
+		about this metaunit - i.e. one doesn't want to parse it immediately
+		but to create a makefile that will parse it. 
+		In this case it allows bld.infs to be parsed in parallel by make."""
+
 		# insert the start time into the Makefile name?
 
-		self.configs = build.GetConfig("build").GenerateBuildUnits()
+		buildconfig = build.GetConfig("build").GenerateBuildUnits(build.cache)
+		self.configs = build.buildUnitsToBuild
 
 		# Pass certain CLI flags through to the makefile-generating sbs calls
 		cli_options = ""
@@ -207,27 +309,38 @@
 			cli_options += " -q"
 
 		
-		nc = len(self.components)
-		number_blocks = 16
+		nc = len(self.children)
+		number_blocks = build.jobs
 		block_size = (nc / number_blocks) + 1
 		component_blocks = []
 		spec_nodes = []
 		
 		b = 0
+		childlist = list(self.children)
 		while b < nc:
-			component_blocks.append(self.components[b:b+block_size])
+			component_blocks.append(childlist[b:b+block_size])
 			b += block_size
 			
-		if len(component_blocks[-1]) <= 0:
+		while len(component_blocks[-1]) <= 0:
 			component_blocks.pop()
-		
+			number_blocks -= 1
+	
+		build.Info("Parallel Parsing: bld.infs split into %d blocks\n", number_blocks)
+		# Cause the binding makefiles to have the toplevel makefile's 
+		# name.  The bindee's have __pp appended.	
+		tm = build.topMakefile.Absolute()
+		binding_makefiles = raptor_makefile.MakefileSet(str(tm.Dir()), build.maker.selectors, makefiles=None, filenamebase=str(tm.File()))		
+		build.topMakefile = generic_path.Path(str(build.topMakefile) + "_pp")
+
 		loop_number = 0
 		for block in component_blocks:
 			loop_number += 1
 			specNode = raptor_data.Specification("metadata_" + self.name)
 
-			componentList = " ".join([str(c) for c in block])
-			configList = " ".join([c.name for c in configs])
+			componentList = " ".join([str(c.bldinf_filename) for c in block])
+
+			
+			configList = " ".join([c.name for c in self.configs if c.name != "build" ])
 			
 			makefile_path = str(build.topMakefile) + "_" + str(loop_number)
 			try:
@@ -247,8 +360,6 @@
 				var.AddOperation(raptor_data.Set("NO_BUILD", "1"))
 			specNode.AddVariant(var)
 	
-	
-	
 			try:
 				interface = build.cache.FindNamedInterface("build.makefiles")
 				specNode.SetInterface(interface)
@@ -256,15 +367,28 @@
 				build.Error("Can't find flm interface 'build.makefiles' ")
 				
 			spec_nodes.append(specNode)
-			
-			
+			binding_makefiles.addInclude(str(makefile_path)+"_all")
+
+		ppstart = time.time()
+		build.Info("Parallel Parsing: time: Start %d", int(ppstart))
+		m = self.realise_makefile(build, spec_nodes)
+		m.close()
+		gen_result = build.Make(m)
 
-		## possibly some error handling here?
-
-		self.specs = spec_nodes
+		ppfinish = time.time()
+		build.Info("Parallel Parsing: time: Finish %d", int(ppfinish))
+		build.Info("Parallel Parsing: time: Parse Duration %d", int(ppfinish - ppstart))
+		build.Debug("Binding Makefile base name is %s ", binding_makefiles.filenamebase)
+		binding_makefiles.close()
+		b = build.Make(binding_makefiles)
+		buildfinish = time.time()
+		build.Info("Parallel Parsing: time: Build Duration %d", int(buildfinish - ppfinish))
+		return b
 
 
-class BuildCompleteException(Exception):
+
+
+class BuildCannotProgressException(Exception):
 	pass
 
 # raptor module classes
@@ -326,8 +450,8 @@
 		# things to initialise
 		self.args = []
 
-		self.componentGroups = []
-		self.orderComponentGroups = False
+		self.layers = []
+		self.orderLayers = False
 		self.commandlineComponents = []
 
 		self.systemModel = None
@@ -374,6 +498,9 @@
 		return True
 
 	def AddConfigName(self, name):
+		if name == "build":
+			traceback.print_stack((sys.stdout))
+			sys.exit(1)
 		self.configNames.append(name)
 		return True
 
@@ -507,6 +634,8 @@
 		type = type.lower()
 		if type == "on":
 			self.doParallelParsing = True
+		elif type == "slave":
+			self.isParallelParsingSlave = True
 		elif type == "off":
 			self.doParallelParsing = False
 		else:
@@ -529,7 +658,7 @@
 
 	def PrintVersion(self,dummy):
 		global name
-		print name, "version", raptor_version.Version()
+		print name, "version", raptor_version.fullversion()
 		self.mission = Raptor.M_VERSION
 		return False
 
@@ -538,7 +667,7 @@
 	def Introduction(self):
 		"""Print a header of useful information about Raptor"""
 
-		self.Info("%s: version %s\n", name, raptor_version.Version())
+		self.Info("%s: version %s\n", name, raptor_version.fullversion())
 
 		self.Info("%s %s", env, str(self.home))
 		self.Info("Set-up %s", str(self.raptorXML))
@@ -547,7 +676,7 @@
 		
 		# the inherited environment
 		for e, value in os.environ.items():
-			self.Info("Environment %s=%s", e, value)
+			self.Info("Environment %s=%s", e, value.replace("]]>", "]]&gt;"))
 
 		# and some general debug stuff
 		self.Debug("Platform %s", "-".join(hostplatform))
@@ -704,9 +833,11 @@
 
 
 		for c in set(configNames):
+			self.Debug("BuildUnit: %s", c)
 			try:		
 				x = self.GetConfig(c)
-				buildUnitsToBuild.update( x.GenerateBuildUnits() )
+				gb = x.GenerateBuildUnits(self.cache) 
+				buildUnitsToBuild.update( gb )
 			except Exception, e:
 				self.FatalError(str(e))
 
@@ -770,13 +901,13 @@
 				systemModel.DumpLayerInfo(layer)
 
 				if systemModel.IsLayerBuildable(layer):
-					layersToBuild.append(ComponentGroup(layer,
+					layersToBuild.append(Layer(layer,
 							systemModel.GetLayerComponents(layer)))
 
 		return layersToBuild
 
 
-	# Add bld.inf or system definition xml to command line componentGroups (depending on preference)
+	# Add bld.inf or system definition xml to command line layers (depending on preference)
 	def FindSysDefIn(self, aDir = None):
 		# Find a system definition file
 
@@ -808,15 +939,6 @@
 
 		return None
 
-	def AttachSpecs(self, groups):
-		# tell the specs which Raptor object they work for (so that they can
-		# access the cache and issue warnings and errors)
-		for spec in groups:
-			spec.SetOwner(self)
-			self.Info("Buildable specification '%s'", spec.name)
-			if self.debugOutput:
-				spec.DebugPrint()
-
 	def GenerateGenericSpecs(self, configsToBuild):
 		# if a Configuration has any config-wide interfaces
 		# then add a Specification node to call each of them.
@@ -832,7 +954,7 @@
 					filter.AddConfigCondition(c.name)
 				else:
 					# create a new node
-					filter = raptor_data.Filter("config_wide")
+					filter = raptor_data.Filter(name = "config_wide")
 					filter.AddConfigCondition(c.name)
 					for i in iface.split():
 						spec = raptor_data.Specification(i)
@@ -842,50 +964,25 @@
 					configWide[iface] = filter
 					genericSpecs.append(filter)
 
-		self.AttachSpecs(genericSpecs)
-
 		return genericSpecs
 
 
-	def WriteMetadataDepsMakefile(self, component_group):
-		""" Takes a list of (filename, target) tuples that indicate where """
-		# Create a Makefile that includes all the dependency information for this spec group
-		build_metamakefile_name = \
-				os.path.abspath(sbs_build_dir).replace('\\','/').rstrip('/') + \
-				'/metadata_%s.mk' % component_group.name.lower()
-		bmkmf = open(build_metamakefile_name, "w+")
-		bmkmf.write("# Build Metamakefile - Dependencies for metadata during the 'previous' build\n\n")
-		bmkmf.write("PARSETARGET:=%s\n" % build_metamakefile_name)
-		bmkmf.write("%s:  \n" % build_metamakefile_name)
-		bmkmf.write("\t@echo -e \"\\nRE-RUNNING SBS with previous parameters\"\n")
-		bmkmf.write("\t@echo pretend-sbs %s\n" % " ".join(self.args))
-		try:
-			for m in component_group.dependencies:
-				filename, target = m
-				bmkmf.write("-include %s\n\n" % filename)
-		finally:
-			bmkmf.close()
-
-		return build_metamakefile_name
-
-
 	def GetEvaluator(self, specification, configuration, gathertools=False):
 		""" this will perform some caching later """
-		return raptor_data.Evaluator(self, specification, configuration, gathertools=gathertools)
-
-
-	def areMakefilesUptodate(self):
-		return False
+		return raptor_data.Evaluator(specification, configuration, gathertools=gathertools, cache = self.cache)
 
 
-	def Make(self, makefile):
+	def Make(self, makefileset):
+		if not self.noBuild and makefileset is not None:
+			if self.maker.Make(makefileset):
+				self.Info("The make-engine exited successfully.")
+				return True
+			else:
+				self.Error("The make-engine exited with errors.")
+				return False
+		else:
+			self.Info("No build performed")
 
-		if self.maker.Make(makefile):
-			self.Info("The make-engine exited successfully.")
-			return True
-		else:
-			self.Error("The make-engine exited with errors.")
-			return False
 
 
 	def Report(self):
@@ -898,10 +995,10 @@
 		self.Info("Run time %s seconds" % self.runtime)
 
 	def AssertBuildOK(self):
-		"""Raise a BuildCompleteException if no further processing is required
+		"""Raise a BuildCannotProgressException if no further processing is required
 		"""
 		if self.Skip():
-			raise BuildCompleteException("")
+			raise BuildCannotProgressException("")
 
 		return True
 
@@ -937,13 +1034,12 @@
 			schema = "http://symbian.com/xml/build/log/1_0.xsd"
 
 			self.out.write("<buildlog sbs_version=\"%s\" xmlns=\"%s\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"%s %s\">\n"
-						   % (raptor_version.Version(), namespace, namespace, schema))
+						   % (raptor_version.fullversion(), namespace, namespace, schema))
 			self.logOpen = True
 		except Exception,e:
 			self.out = sys.stdout # make sure that we can actually get errors out.
 			self.logOpen = False
-			self.FatalError("Unable to open the output logs: %s" % str(e))
-
+			self.FatalError("<error>Unable to open the output logs: %s" % str(e))
 
 	def CloseLog(self):
 		if self.logOpen:
@@ -1019,28 +1115,11 @@
 		if format:
 			self.out.write(format % extras)
 
-
-	def MakeComponentGroup(self, cg):
-		if not self.maker:
-			self.maker = raptor_make.MakeEngine(self)
-
-		if self.maker == None:
-			self.Error("No make engine present")
-			return None
-
-		makefile = cg.CreateMakefile(self.topMakefile, self.maker, self.systemDefinitionOrderLayers)
-		if (not self.noBuild and makefile is not None) \
-				or self.doParallelParsing:
-			# run the build for a single group of specs
-			self.Make(makefile)
-		else:
-			self.Info("No build performed for %s" % cg.name)
-
-	def GetComponentGroupsFromCLI(self):
-		"""Returns the list of componentGroups as specified by the
+	def GetLayersFromCLI(self):
+		"""Returns the list of layers as specified by the
 		   commandline interface to Raptor e.g. parameters
 		   or the current directory"""
-		componentGroups=[]
+		layers=[]
 		# Look for bld.infs or sysdefs in the current dir if none were specified
 		if self.systemDefinitionFile == None and len(self.commandlineComponents) == 0:
 			if not self.preferBuildInfoToSystemDefinition:
@@ -1049,38 +1128,39 @@
 				if self.systemDefinitionFile == None:
 					aComponent = self.FindComponentIn(cwd)
 					if aComponent:
-						componentGroups.append(ComponentGroup('default',[aComponent]))
+						layers.append(Layer('default',[aComponent]))
 			else:
 				aComponent = self.FindComponentIn(cwd)
 				if aComponent is None:
 					self.systemDefinitionFile = self.FindSysDefIn(cwd)
 				else:
-					componentGroups.append(ComponentGroup('default',[aComponent]))
+					layers.append(Layer('default',[aComponent]))
 
-			if len(componentGroups) <= 0 and  self.systemDefinitionFile == None:
+			if len(layers) <= 0 and  self.systemDefinitionFile == None:
 				self.Warn("No default bld.inf or system definition file found in current directory (%s)", cwd)
 
 		# If we now have a System Definition to parse then get the layers of components
 		if self.systemDefinitionFile != None:
 			systemModel = raptor_xml.SystemModel(self, self.systemDefinitionFile, self.systemDefinitionBase)
-			componentGroups = self.GatherSysModelLayers(systemModel, self.systemDefinitionRequestedLayers)
+			layers = self.GatherSysModelLayers(systemModel, self.systemDefinitionRequestedLayers)
 			
 		# Now get components specified on a commandline - build them after any
 		# layers in the system definition.
 		if len(self.commandlineComponents) > 0:
-			componentGroups.append(ComponentGroup('commandline',self.commandlineComponents))
+			layers.append(Layer('commandline',self.commandlineComponents))
 
 		# If we aren't building components in order then flatten down
 		# the groups
 		if not self.systemDefinitionOrderLayers:
 			# Flatten the layers into one group of components if
 			# we are not required to build them in order.
-			newcg = ComponentGroup("all")
-			for cg in componentGroups:
-				newcg.extend(cg)
-			componentGroups = [newcg]
+			newcg = Layer("all")
+			for cg in layers:
+				for c in cg:
+					newcg.add(c)
+			layers = [newcg]
 
-		return componentGroups
+		return layers
 
 	def Build(self):
 
@@ -1102,20 +1182,21 @@
 
 			# find out what configurations to build
 			self.AssertBuildOK()
-			buildUnitsToBuild = set()
 			buildUnitsToBuild = self.GetBuildUnitsToBuild(self.configNames)
 
+			self.buildUnitsToBuild = buildUnitsToBuild
+
 			# find out what components to build, and in what way
-			componentGroups = []
+			layers = []
 
 			self.AssertBuildOK()
 			if len(buildUnitsToBuild) >= 0:
-				componentGroups = self.GetComponentGroupsFromCLI()
+				layers = self.GetLayersFromCLI()
 
-			componentCount = reduce(lambda x,y : x + y, [len(cg) for cg in componentGroups])
+			componentCount = reduce(lambda x,y : x + y, [len(cg) for cg in layers])
 
 			if not componentCount > 0:
-				raise BuildCompleteException("No components to build.")
+				raise BuildCannotProgressException("No components to build.")
 
 			# check the configurations (tools versions)
 			self.AssertBuildOK()
@@ -1127,31 +1208,30 @@
 
 			self.AssertBuildOK()
 
+			# Setup a make engine.
+			if not self.maker:
+				self.maker = raptor_make.MakeEngine(self)
+				if self.maker == None:
+					self.Error("No make engine present")
 
-			# if self.doParallelParsing and not (len(componentGroups) == 1 and len(componentGroups[0]) == 1):
+			self.AssertBuildOK()
+
+			# if self.doParallelParsing and not (len(layers) == 1 and len(layers[0]) == 1):
 			if self.doParallelParsing:
 				# Create a Makefile to parse components in parallel and build them
-				for cg in componentGroups:
-					cg.GenerateMetadataSpecs(buildUnitsToBuild)
-					self.MakeComponentGroup(cg)
-				if self.noBuild:
-					self.Info("No build performed")
+				for l in layers:
+					l.meta_realise(self)
 			else:
 				# Parse components serially, creating one set of makefiles
 				# create non-component specs
-				self.AssertBuildOK()
-				generic_specs = self.GenerateGenericSpecs(buildUnitsToBuild)
+				self.generic_specs = self.GenerateGenericSpecs(buildUnitsToBuild)
 
 				self.AssertBuildOK()
-				for cg in componentGroups:
+				for l in layers:
 					# create specs for a specific group of components
-					cg.GenerateSpecs(generic_specs, buildUnitsToBuild)
-					self.WriteMetadataDepsMakefile(cg)	
+					l.realise(self)
 					
-					# generate the makefiles for one group of specs
-					self.MakeComponentGroup(cg)
-
-		except BuildCompleteException,b:
+		except BuildCannotProgressException,b:
 			if str(b) != "":
 				self.Info(str(b))
 
@@ -1212,17 +1292,7 @@
 	# object which represents a build
 	b = Raptor.CreateCommandlineBuild(argv)
 
-	# allow all objects to log to the
-	# build they're being used in
-	global build
-	global log
-	build = b
-	log = b
-
-
-	result = b.Build()
-
-	return result
+	return b.Build()
 
 
 def DisplayBanner():
@@ -1231,4 +1301,5 @@
 
 
 
+
 # end of the raptor module
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/python/raptor_buildplatform.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,158 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+# Classes, methods and regex available for use in log filters
+#
+
+# This particular file is preliminary and under development.
+
+class BuildPlatform(object):
+	""" A build platform is a set of configurations which share
+	the same metadata. In other words, a set of configurations
+	for which the bld.inf and MMP files pre-process to exactly
+	the same text."""
+
+	def __init__(self, build):
+		evaluator = build.GetEvaluator(None, buildConfig)
+		self.selfform= evaluator.CheckedGet("TRADITIONAL_PLATFORM")
+		epocroot = evaluator.CheckedGet("EPOCROOT")
+		self.epocroot = generic_path.Path(epocroot)
+
+		sbs_build_dir = evaluator.CheckedGet("SBS_BUILD_DIR")
+		self.sbs_build_dir = generic_path.Path(sbs_build_dir)
+		flm_export_dir = evaluator.CheckedGet("FLM_EXPORT_DIR")
+		self.flm_export_dir = generic_path.Path(flm_export_dir)
+		self.cacheid = flm_export_dir
+		if raptor_utilities.getOSPlatform().startswith("win"):
+			self.platmacros = evaluator.CheckedGet( "PLATMACROS.WINDOWS")
+		else:
+			self.platmacros = evaluator.CheckedGet( "PLATMACROS.LINUX")
+
+
+		# is this a feature variant config or an ordinary variant
+		fv = evaluator.Get("FEATUREVARIANTNAME")
+		if fv:
+			variantHdr = evaluator.CheckedGet("VARIANT_HRH")
+			variantHRH = generic_path.Path(variantHdr)
+			self.isfeaturevariant = True
+		else:
+			variantCfg = evaluator.CheckedGet("VARIANT_CFG")
+			variantCfg = generic_path.Path(variantCfg)
+			if not variantCfg in variantCfgs:
+				# get VARIANT_HRH from the variant.cfg file
+				varCfg = getVariantCfgDetail(self.epocroot, variantCfg)
+				variantCfgs[variantCfg] = varCfg['VARIANT_HRH']
+				# we expect to always build ABIv2
+				if not 'ENABLE_ABIV2_MODE' in varCfg:
+					build.Warn("missing flag ENABLE_ABIV2_MODE in %s file. ABIV1 builds are not supported.",
+										   str(variantCfg))
+			variantHRH = variantCfgs[variantCfg]
+			self.isfeaturevariant = False
+
+			self.variant_hrh = variantHRH
+			build.Info("'%s' uses variant hrh file '%s'", buildConfig.name, variantHRH)
+			self.systeminclude = evaluator.CheckedGet("SYSTEMINCLUDE")
+
+
+			# find all the interface names we need
+			ifaceTypes = evaluator.CheckedGet("INTERFACE_TYPES")
+			interfaces = ifaceTypes.split()
+
+			for iface in interfaces:
+				detail[iface] = evaluator.CheckedGet("INTERFACE." + iface)
+
+			# not test code unless positively specified
+			self.testcode = evaluator.CheckedGet("TESTCODE", "")
+
+			# make a key that identifies this platform uniquely
+			# - used to tell us whether we have done the pre-processing
+			# we need already using another platform with compatible values.
+
+			key = str(self.variant_hrh) \
+				+ str(self.epocroot) \
+			+ self.systeminclude \
+			+ self.platform
+
+			# Keep a short version of the key for use in filenames.
+			uniq = hashlib.md5()
+			uniq.update(key)
+
+			plat.key = key
+			plat.key_md5 = "p_" + uniq.hexdigest()
+			del uniq
+
+	def __hash__(self):
+		return hash(self.platform) + hash(self.epocroot) + hash(self.variant_hrh) + hash(self.systeminclude) + hash(self.testcode)
+
+	def __cmp__(self,other):
+		return cmp(self.hash(), other.hash())
+
+
+	@classmethod 
+	def fromConfigs(configsToBuild, build):
+		""" Group the list of configurations into "build platforms"."""
+		platforms = Set()
+		
+		for buildConfig in configsToBuild:
+			# get everything we need to know about the configuration
+			plat = BuildPlatform(build = build)
+
+			# compare this configuration to the ones we have already seen
+
+			# Is this an unseen export platform?
+			# concatenate all the values we care about in a fixed order
+			# and use that as a signature for the exports.
+			items = ['EPOCROOT', 'VARIANT_HRH', 'SYSTEMINCLUDE', 'TESTCODE', 'export']
+			export = ""
+			for i in  items:
+				if i in detail:
+					export += i + str(detail[i])
+
+			if export in exports:
+				# add this configuration to an existing export platform
+				index = exports[export]
+				self.ExportPlatforms[index]['configs'].append(buildConfig)
+			else:
+				# create a new export platform with this configuration
+				exports[export] = len(self.ExportPlatforms)
+				exp = copy.copy(detail)
+				exp['PLATFORM'] = 'EXPORT'
+				exp['configs']  = [buildConfig]
+				self.ExportPlatforms.append(exp)
+
+			# Is this an unseen build platform?
+			# concatenate all the values we care about in a fixed order
+			# and use that as a signature for the platform.
+			items = ['PLATFORM', 'EPOCROOT', 'VARIANT_HRH', 'SYSTEMINCLUDE', 'TESTCODE']
+			if raptor_utilities.getOSPlatform().startswith("win"):
+				items.append('PLATMACROS.WINDOWS')
+			else:
+				items.append('PLATMACROS.LINUX')
+
+			items.extend(interfaces)
+			platform = ""
+			for i in  items:
+				if i in detail:
+					platform += i + str(detail[i])
+
+			if platform in platforms:
+				# add this configuration to an existing build platform
+				index = platforms[platform]
+				BuildPlatforms[index]['configs'].append(buildConfig)
+			else:
+				# create a new build platform with this configuration
+				platforms[platform] = len(self.BuildPlatforms)
+				plat.configs = [buildConfig]
+				BuildPlatforms.append(detail)
+
--- a/sbsv2/raptor/python/raptor_cache.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_cache.py	Mon Nov 16 20:39:37 2009 +0000
@@ -143,7 +143,6 @@
 			self.WarnDuplicate("group", self.groups[obj.name], obj)
 			return
 
-		obj.SetOwner(self.raptor)
 		self.groups[obj.name] = obj
 
 	def FindNamedAlias(self, name):
@@ -154,7 +153,6 @@
 			self.WarnDuplicate("alias", self.aliases[obj.name], obj)
 			return
 
-		obj.SetOwner(self.raptor)
 		self.aliases[obj.name] = obj
 
 
@@ -176,7 +174,6 @@
 			self.WarnDuplicate("interface", self.interfaces[cacheID][obj.name], obj)
 			return
 
-		obj.SetOwner(self.raptor)
 		obj.cacheID = cacheID
 		self.interfaces[cacheID][obj.name] = obj
 
@@ -192,7 +189,6 @@
 				self.WarnDuplicate("variant", self.variants[obj.name], obj)
 				return
 
-			obj.SetOwner(self.raptor)
 			self.variants[obj.name] = obj
 
 
--- a/sbsv2/raptor/python/raptor_cli.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_cli.py	Mon Nov 16 20:39:37 2009 +0000
@@ -148,6 +148,7 @@
 				help="""Controls how metadata (e.g. bld.infs) are parsed in Parallel.
 					Possible values are:
 					"on"  - Parse bld.infs in parallel (should be faster on clusters/multicore machines)
+					"slave" - used internally by Raptor 
 					"off" - Parse bld.infs serially 
 				     """)
 
--- a/sbsv2/raptor/python/raptor_data.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_data.py	Mon Nov 16 20:39:37 2009 +0000
@@ -27,8 +27,13 @@
 import subprocess
 from tempfile import gettempdir
 from time import time, clock
+import traceback
+import raptor_cache
 
 
+class MissingInterfaceError(Exception):
+	def __init__(self, s):
+		Exception.__init__(self,s)
 
 # What host platforms we recognise
 # This allows us to tie some variants to one host platform and some to another
@@ -68,16 +73,14 @@
 class Model(object):
 	"Base class for data-model objects"
 
+	__slots__ = ('host', 'source', 'cacheID')
+
 	def __init__(self):
-		self.owner = None	# Raptor object
 		self.source = None	# XML file
-		self.indent = " "	# for DebugPrint
 		self.host = None
 		self.cacheID = ""	# default set of cached objects
-
-
-	def SetOwner(self, aRaptor):
-		self.owner = aRaptor
+		# not using the cache parameter - there to make the 
+		# init for all Model objects "standard"
 
 
 	def SetSourceFile(self, filename):
@@ -92,10 +95,6 @@
 		raise InvalidChildError()
 
 
-	def DebugPrint(self, prefix = ""):
-		if self.owner:
-			self.owner.Debug("%s", prefix)
-
 	def Valid(self):
 		return False
 
@@ -139,8 +138,7 @@
 	def Resolve(self):
 		raise BadReferenceError()
 
-	def GetModifiers(self):
-		cache = self.owner.cache
+	def GetModifiers(self, cache):
 		return [ cache.FindNamedVariant(m) for m in self.modifiers ]
 
 	def Valid(self):
@@ -154,20 +152,13 @@
 		self.variants = []
 
 
-	def SetOwner(self, aRaptor):
-		Model.SetOwner(self, aRaptor)
-		for v in self.variants:
-			v.SetOwner(aRaptor)
-
-
-	def DebugPrint(self, prefix = ""):
-		for v in self.variants:
-			v.DebugPrint(prefix)
+	def __str__(self):
+		return "\n".join([str(v) for v in self.variants])
 
 
 	def AddVariant(self, variant):
 		if type(variant) is types.StringTypes:
-			variant = VariantRef(variant)
+			variant = VariantRef(ref = variant)
 
 
 		# Only add the variant if it's not in the list
@@ -175,15 +166,19 @@
 		if not variant in self.variants:
 			self.variants.append(variant)
 
-	def GetVariants(self):
+	def GetVariants(self, cache):
 		# resolve any VariantRef objects into Variant objects
+		missing_variants = []
 		for i,var in enumerate(self.variants):
 			if isinstance(var, Reference):
 				try:
-					self.variants[i] = var.Resolve()
+					self.variants[i] = var.Resolve(cache=cache)
 
 				except BadReferenceError:
-					self.owner.Error("Missing variant '%s'", var.ref)
+					missing_variants.append(var.ref)
+
+		if len(missing_variants) > 0:
+			raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants))
 
 		return self.variants
 
@@ -199,27 +194,25 @@
 		self.params = []
 		self.paramgroups = []
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<interface name='%s'>", prefix, self.name)
-		self.owner.Debug("%s...", prefix)
-		self.owner.Debug("%s</interface>", prefix)
+	def __str__(self):
+		return "<interface name='%s'>" % self.name + "</interface>"
 
-	def FindParent(self):
+	def FindParent(self, cache):
 		try:
-			return self.owner.cache.FindNamedInterface(self.extends, self.cacheID)
+			return cache.FindNamedInterface(self.extends, self.cacheID)
 		except KeyError:
 			raise BadReferenceError("Cannot extend interface because it cannot be found: "+str(self.extends))
 
-	def GetParams(self):
+	def GetParams(self, cache):
 		if self.extends != None:
-			parent = self.FindParent()
+			parent = self.FindParent(cache)
 
 			# what parameter names do we have already?
 			names = set([x.name for x in self.params])
 
 			# pick up ones we don't have that are in our parent
 			pp = []
-			for p in parent.GetParams():
+			for p in parent.GetParams(cache):
 				if not p.name in names:
 					pp.append(p)
 
@@ -229,29 +222,29 @@
 
 		return self.params
 
-	def GetParamGroups(self):
+	def GetParamGroups(self, cache):
 		if self.extends != None:
-			parent = self.FindParent()
+			parent = self.FindParent(cache)
 
 			# what parameter names do we have already?
 			patterns = set([x.pattern for x in self.paramgroups])
 
 			# pick up ones we don't have that are in our parent
-			for g in parent.GetParamGroups():
+			for g in parent.GetParamGroups(cache):
 				if not g.pattern in patterns:
 					self.paramgroups.append(g)
 
 		return self.paramgroups
 
 
-	def GetFLMIncludePath(self):
+	def GetFLMIncludePath(self, cache):
 		"absolute path to the FLM"
 
 		if self.flm == None:
 			if self.extends != None:
-				parent = self.FindParent()
+				parent = self.FindParent(cache)
 
-				return parent.GetFLMIncludePath()
+				return parent.GetFLMIncludePath(cache)
 			else:
 				raise InvalidPropertyError()
 
@@ -295,12 +288,12 @@
 
 class InterfaceRef(Reference):
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<interfaceRef ref='%s'/>", prefix, self.ref)
+	def __str__(self):
+		return "<interfaceRef ref='%s'/>" % self.ref
 
-	def Resolve(self):
+	def Resolve(self, cache):
 		try:
-			return self.owner.cache.FindNamedInterface(self.ref, self.cacheID)
+			return cache.FindNamedInterface(self.ref, self.cacheID)
 		except KeyError:
 			raise BadReferenceError()
 
@@ -316,24 +309,13 @@
 		self.parentSpec = None
 
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<spec name='%s'>", prefix, self.name)
-		if self.interface:
-			self.interface.DebugPrint(prefix + self.indent)
-		VariantContainer.DebugPrint(self, prefix + self.indent)
+	def __str__(self):
+		s = "<spec name='%s'>" % str(self.name)
+		s += VariantContainer.__str__(self)
 		for c in self.childSpecs:
-			c.DebugPrint(prefix + self.indent)
-		self.owner.Debug("%s</spec>", prefix)
-
-
-	def SetOwner(self, aRaptor):
-		VariantContainer.SetOwner(self, aRaptor)
-
-		if self.interface != None:
-			self.interface.SetOwner(aRaptor)
-
-		for s in self.childSpecs:
-			s.SetOwner(aRaptor)
+			s += str(c) + '\n'
+		s += "</spec>"
+		return s
 
 
 	def SetProperty(self, name, value):
@@ -343,10 +325,10 @@
 			raise InvalidPropertyError()
 
 
-	def Configure(self, config):
+	def Configure(self, config, cache):
 		# configure all the children (some may be Filters or parents of)
 		for spec in self.GetChildSpecs():
-			spec.Configure(config)
+			spec.Configure(config, cache = cache)
 
 
 	def HasInterface(self):
@@ -358,10 +340,10 @@
 		or isinstance(interface, InterfaceRef):
 			self.interface = interface
 		else:
-			self.interface = InterfaceRef(interface)
+			self.interface = InterfaceRef(ref = interface)
 
 
-	def GetInterface(self):
+	def GetInterface(self, cache):
 		"""return the Interface (fetching from the cache if it was a ref)
 		may return None"""
 
@@ -371,13 +353,11 @@
 
 		if isinstance(self.interface, InterfaceRef):
 			try:
-				self.interface = self.interface.Resolve()
+				self.interface = self.interface.Resolve(cache=cache)
 				return self.interface
 
 			except BadReferenceError:
-				self.owner.Error("Missing interface %s", self.interface.ref)
-				return None
-
+				raise MissingInterfaceError("Missing interface %s" % self.interface.ref)
 
 	def AddChild(self, child):
 		if isinstance(child, Specification):
@@ -409,7 +389,7 @@
 		return True
 
 
-	def GetAllVariantsRecursively(self):
+	def GetAllVariantsRecursively(self, cache):
 		"""Returns all variants contained in this node and in its ancestors.
 
 		The returned value is a list, the structure of which is [variants-in-parent,
@@ -419,11 +399,11 @@
 		the variants themselves.
 		"""
 		if self.parentSpec:
-			variants = self.parentSpec.GetAllVariantsRecursively()
+			variants = self.parentSpec.GetAllVariantsRecursively(cache = cache)
 		else:
 			variants = []
 
-		variants.extend( self.GetVariants() )
+		variants.extend( self.GetVariants(cache = cache) )
 
 		return variants
 
@@ -438,22 +418,21 @@
 	If several Conditions are set, the test is an OR of all of them."""
 
 	def __init__(self, name = ""):
-		Specification.__init__(self, name)	# base class constructor
-		self.Else = Specification(name)     # same for Else part
+		Specification.__init__(self, name = name)	# base class constructor
+		self.Else = Specification(name = name)     # same for Else part
 		self.isTrue = True
 		self.configNames = set()            #
 		self.variableNames = set()          # TO DO: Condition class
 		self.variableValues = {}            #
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<filter name='%s'>", prefix, self.name)
-		self.owner.Debug("%s <if config='%s'>", prefix, " | ".join(self.configNames))
-		Specification.DebugPrint(self, prefix + self.indent)
-		self.owner.Debug("%s </if>", prefix)
-		self.owner.Debug("%s <else>", prefix)
-		self.Else.DebugPrint(prefix + self.indent)
-		self.owner.Debug("%s </else>", prefix)
-		self.owner.Debug("%s</filter>", prefix)
+	def __str__(self, prefix = ""):
+		s = "<filter name='%s'>\n"% self.name
+		s += "<if config='%s'>\n" % " | ".join(self.configNames)
+		s += Specification.__str__(self)
+		s += "</if>\n <else>\n"
+		s += str(self.Else)
+		s += " </else>\n</filter>\n"
+		return s
 
 
 	def SetConfigCondition(self, configName):
@@ -478,13 +457,14 @@
 			self.variableValues[variableName] = set([variableValues])
 
 
-	def Configure(self, buildUnit):
+	def Configure(self, buildUnit, cache):
 		self.isTrue = False
 
 		if buildUnit.name in self.configNames:
 			self.isTrue = True
 		elif self.variableNames:
-			evaluator = self.owner.GetEvaluator(self.parentSpec, buildUnit)
+
+			evaluator = Evaluator(self.parentSpec, buildUnit, cache=cache)
 
 			for variableName in self.variableNames:
 				variableValue = evaluator.Get(variableName)
@@ -495,14 +475,7 @@
 
 		# configure all the children too
 		for spec in self.GetChildSpecs():
-			spec.Configure(buildUnit)
-
-
-	def SetOwner(self, aRaptor):
-		# base class method
-		Specification.SetOwner(self, aRaptor)
-		# same for Else part
-		self.Else.SetOwner(aRaptor)
+			spec.Configure(buildUnit, cache=cache)
 
 
 	def HasInterface(self):
@@ -512,18 +485,18 @@
 			return self.Else.HasInterface()
 
 
-	def GetInterface(self):
+	def GetInterface(self, cache):
 		if self.isTrue:
-			return Specification.GetInterface(self)
+			return Specification.GetInterface(self, cache = cache)
 		else:
-			return self.Else.GetInterface()
+			return self.Else.GetInterface(cache = cache)
 
 
-	def GetVariants(self):
+	def GetVariants(self, cache):
 		if self.isTrue:
-			return Specification.GetVariants(self)
+			return Specification.GetVariants(self, cache = cache)
 		else:
-			return self.Else.GetVariants()
+			return self.Else.GetVariants(cache = cache)
 
 
 	def SetParentSpec(self, parent):
@@ -591,18 +564,17 @@
 
 class Operation(Model):
 	"Base class for variant operations"
+	__slots__ = 'type'
 	def __init__(self):
 		Model.__init__(self)	# base class constructor
 		self.type = None
 
-
 	def Apply(self, oldValue):
 		pass
 
 
 class Append(Operation):
-	__slots__ = ('name','value','separator','owner')
-
+	__slots__ = ('name', 'value', 'separator')
 	def __init__(self, name = None, value = None, separator = " "):
 		Operation.__init__(self)	# base class constructor
 		self.name = name
@@ -610,9 +582,9 @@
 		self.separator = separator
 
 
-	def DebugPrint(self, prefix = ""):
+	def __str__(self):
 		attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'"
-		self.owner.Debug("%s<append %s/>", prefix, attributes)
+		return "<append %s/>" % attributes
 
 
 	def Apply(self, oldValue):
@@ -641,6 +613,7 @@
 
 
 class Prepend(Operation):
+	__slots__ = ('name', 'value', 'separator')
 	def __init__(self, name = None, value = None, separator = " "):
 		Operation.__init__(self)	# base class constructor
 		self.name = name
@@ -648,9 +621,9 @@
 		self.separator = separator
 
 
-	def DebugPrint(self, prefix = ""):
+	def __str__(self, prefix = ""):
 		attributes = "name='" + self.name + "' value='" + self.value + "' separator='" + self.separator + "'"
-		self.owner.Debug("%s<prepend %s/>", prefix, attributes)
+		return "<prepend %s/>" % prefix
 
 
 	def Apply(self, oldValue):
@@ -679,8 +652,8 @@
 
 
 class Set(Operation):
+	__slots__ = ('name', 'value', 'type', 'versionCommand', 'versionResult')
 	"""implementation of <set> operation"""
-	__slots__ = ('name','value', 'type', 'versionCommand', 'versionResult', 'owner')
 
 	def __init__(self, name = None, value = "", type = ""):
 		Operation.__init__(self)	# base class constructor
@@ -691,12 +664,12 @@
 		self.versionResult = ""
 
 
-	def DebugPrint(self, prefix = ""):
+	def __str__(self):
 		attributes = "name='" + self.name + "' value='" + self.value + "' type='" + self.type + "'"
 		if type == "tool":
 			attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult
 
-		self.owner.Debug("%s<set %s/>", prefix, attributes)
+		return "<set %s/>" % attributes
 
 
 	def Apply(self, oldValue):
@@ -724,6 +697,8 @@
 	def Valid(self):
 		return (self.name != None and self.value != None)
 
+class BadToolValue(Exception):
+	pass
 
 class Env(Set):
 	"""implementation of <env> operator"""
@@ -733,7 +708,7 @@
 		self.default = default
 
 
-	def DebugPrint(self, prefix = ""):
+	def __str__(self):
 		attributes = "name='" + self.name + "' type='" + self.type + "'"
 		if default != None:
 			attributes += " default='" + self.default + "'"
@@ -741,7 +716,7 @@
 		if type == "tool":
 			attributes += " versionCommand='" + self.versionCommand + "' versionResult='" + self.versionResult + "'"
 
-		self.owner.Debug("%s<env %s/>", prefix, attributes)
+		return "<env %s/>" % attributes
 
 
 	def Apply(self, oldValue):
@@ -755,14 +730,12 @@
 					path = generic_path.Path(value)
 					value = str(path.Absolute())
 				except ValueError,e:
-					self.owner.Error("the environment variable %s is incorrect: %s" % (self.name, str(e)))
-					return "NO_VALUE_FOR_" + self.name
+					raise BadToolValue("the environment variable %s is incorrect: %s" % (self.name, str(e)))
 		except KeyError:
 			if self.default != None:
 				value = self.default
 			else:
-				self.owner.Error("%s is not set in the environment and has no default", self.name)
-				return "NO_VALUE_FOR_" + self.name
+				raise BadToolValue("%s is not set in the environment and has no default" % self.name)
 
 		return value
 
@@ -791,7 +764,7 @@
 		self.operations = []
 		self.variantKey = ""
 
-	def GetOperations(self):
+	def GetOperations(self, cache):
 		"""Return all operations related to this BuildUnit.
 		
 		The result is cached, and so will only be computed once per BuildUnit.
@@ -800,7 +773,7 @@
 		if self.variantKey != key:
 			self.variantKey = key
 			for v in self.variants:
-				self.operations.extend( v.GetAllOperationsRecursively() )
+				self.operations.extend( v.GetAllOperationsRecursively(cache=cache) )
 
 		return self.operations
 
@@ -820,7 +793,7 @@
 	def ClearModifiers(self):
 		self.modifiers = []
 
-	def GenerateBuildUnits(self):
+	def GenerateBuildUnits(self,cache):
 		"""Returns a list of BuildUnits.
 
 		This function must be overridden by derived classes.
@@ -830,6 +803,8 @@
 
 class Variant(Model, Config):
 
+	__slots__ = ('cache','name','host','extends','ops','variantRefs','allOperations')
+
 	def __init__(self, name = ""):
 		Model.__init__(self)
 		Config.__init__(self)
@@ -868,20 +843,10 @@
 	def Valid(self):
 		return self.name
 
-	def SetOwner(self, aRaptor):
-
-		Model.SetOwner(self, aRaptor)
-
-		for r in self.variantRefs:
-			r.SetOwner(aRaptor)
-
-		for op in self.ops:
-			op.SetOwner(aRaptor)
-
 	def AddOperation(self, op):
 		self.ops.append(op)
 
-	def GetAllOperationsRecursively(self):
+	def GetAllOperationsRecursively(self, cache):
 		"""Returns a list of all operations in this variant.
 
 		The list elements are themselves lists; the overall structure of the
@@ -892,16 +857,16 @@
 
 		if not self.allOperations:
 			if self.extends:
-				parent = self.owner.cache.FindNamedVariant(self.extends)
-				self.allOperations.extend( parent.GetAllOperationsRecursively() )
+				parent = cache.FindNamedVariant(self.extends)
+				self.allOperations.extend( parent.GetAllOperationsRecursively(cache = cache) )
 			for r in self.variantRefs:
-				for v in [ r.Resolve() ] + r.GetModifiers():
-					self.allOperations.extend( v.GetAllOperationsRecursively() )
+				for v in [ r.Resolve(cache = cache) ] + r.GetModifiers(cache = cache):
+					self.allOperations.extend( v.GetAllOperationsRecursively(cache = cache) )
 			self.allOperations.append(self.ops)
 
 		return self.allOperations
 
-	def GenerateBuildUnits(self):
+	def GenerateBuildUnits(self,cache):
 
 		name = self.name
 		vars = [self]
@@ -909,32 +874,32 @@
 		for m in self.modifiers:
 			name = name + "." + m.name
 			vars.append(m)
-
-		return [ BuildUnit(name, vars) ]
-
-	def DebugPrint(self, prefix = ""):
+		return [ BuildUnit(name=name, variants=vars) ]
 
-		self.owner.Debug("%s<var name='%s' extends='%s'>", prefix, self.name, self.extends)
+	def __str__(self):
+		s = "<var name='%s' extends='%s'>\n" % (self.name, self.extends)
 		for op in self.ops:
-			op.DebugPrint(prefix + self.indent)
+			s +=  str(op) + '\n'
+		s += "</var>"
+		return s
 
-		self.owner.Debug("%s</var>", prefix)
-
-
+import traceback
 class VariantRef(Reference):
 
 	def __init__(self, ref=None):
-		Reference.__init__(self, ref)
+		Reference.__init__(self, ref = ref)
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<varRef ref='%s'/>", prefix, self.ref)
+	def __str__(self):
+		return "<varRef ref='%s'/>" % self.ref
 
-	def Resolve(self):
+	def Resolve(self, cache):
 		try:
-			return self.owner.cache.FindNamedVariant(self.ref)
-		except KeyError:
+			return cache.FindNamedVariant(self.ref)
+		except KeyError, e:
 			raise BadReferenceError(self.ref)
 
+class MissingVariantException(Exception):
+	pass
 
 class Alias(Model, Config):
 
@@ -946,8 +911,8 @@
 		self.varRefs = []
 		self.variants = []
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<alias name='%s' meaning='%s'/>", prefix, self.name, self.meaning)
+	def __str__(self):
+		return "<alias name='%s' meaning='%s'/>" % (self.name, self.meaning)
 
 	def SetProperty(self, key, val):
 		if key == "name":
@@ -956,32 +921,31 @@
 			self.meaning = val
 
 			for u in val.split("."):
-				self.varRefs.append( VariantRef(u) )
+				self.varRefs.append( VariantRef(ref = u) )
 		else:
 			raise InvalidPropertyError()
 
-	def SetOwner(self, raptor):
-		Model.SetOwner(self, raptor)
-		for r in self.varRefs:
-			r.SetOwner(raptor)
-
 	def Valid(self):
 		return self.name and self.meaning
 
-	def GenerateBuildUnits(self):
+	def GenerateBuildUnits(self, cache):
 		if not self.variants:
+			missing_variants = []
 			for r in self.varRefs:
 				try:
-					self.variants.append( r.Resolve() )
+					self.variants.append( r.Resolve(cache=cache) )
 				except BadReferenceError:
-					self.owner.Error("Missing variant '%s'", r.ref)
+					missing_variants.append(r.ref)
+				
+			if len(missing_variants) > 0:
+				raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants))
 
 		name = self.name
 
 		for v in self.modifiers:
 			name = name + "." + v.name
 
-		return [ BuildUnit(name, self.variants + self.modifiers) ]
+		return [ BuildUnit(name=name, variants=self.variants + self.modifiers) ]
 
 
 class AliasRef(Reference):
@@ -989,12 +953,12 @@
 	def __init__(self, ref=None):
 		Reference.__init__(self, ref)
 
-	def DebugPrint(self, prefix = ""):
-		self.owner.Debug("%s<aliasRef ref='%s'/>", prefix, self.ref)
+	def __str__(self):
+		return "<aliasRef ref='%s'/>" % self.ref
 
-	def Resolve(self):
+	def Resolve(self, cache):
 		try:
-			return self.owner.cache.FindNamedAlias(self.ref)
+			return cache.FindNamedAlias(self.ref)
 		except KeyError:
 			raise BadReferenceError(self.ref)
 
@@ -1018,41 +982,37 @@
 		else:
 			raise InvalidChildError()
 
-	def SetOwner(self, raptor):
-		Model.SetOwner(self, raptor)
-		for r in self.childRefs:
-			r.SetOwner(raptor)
-
 	def Valid(self):
 		return self.name and self.childRefs
 
-	def DebugPrint(self, prefix = ""):
-
-		self.owner.Debug("<group name='%s'>", prefix, self.name)
-
+	def __str__(self):
+		s = "<group name='%s'>" % self.name
 		for r in self.childRefs:
-			r.DebugPrint(prefix + self.indent)
+			s += str(r)
+		s += "</group>"
+		return s
 
-		self.owner.Debug("%s</group>", prefix)
-
-	def GenerateBuildUnits(self):
-
+	def GenerateBuildUnits(self, cache):
 		units = []
 
+		missing_variants = []
 		for r in self.childRefs:
-			refMods = r.GetModifiers()
+			refMods = r.GetModifiers(cache)
 
 			try:
-				obj = r.Resolve()
+				obj = r.Resolve(cache=cache)
 			except BadReferenceError:
-				self.owner.Error("Missing variant '%s'", r.ref)
+				missing_variants.append(r.ref)
 			else:
 				obj.ClearModifiers()
 
 				for m in refMods + self.modifiers:
 					obj.AddModifier(m)
 
-				units.extend( obj.GenerateBuildUnits() )
+				units.extend( obj.GenerateBuildUnits(cache) )
+
+		if len(missing_variants) > 0:
+			raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants))
 
 		return units
 
@@ -1062,19 +1022,27 @@
 	def __init__(self, ref=None):
 		Reference.__init__(self, ref)
 
-	def DebugPrint(self, prefix = ""):
-		mod = ".".join(self.modifiers)
-		self.owner.Debug("%s<groupRef ref='%s' mod='%s'/>", prefix, self.ref, mod)
+	def __str__(self):
+		return "<%s /><groupRef ref='%s' mod='%s'/>" % (prefix, self.ref, ".".join(self.modifiers))
 
-	def Resolve(self):
+	def Resolve(self, cache):
 		try:
-			return self.owner.cache.FindNamedGroup(self.ref)
+			return cache.FindNamedGroup(self.ref)
 		except KeyError:
 			raise BadReferenceError(self.ref)
 
+class ToolErrorException(Exception):
+	def __init__(self, s):
+		Exception.__init__(self,s)
+
 class Tool(object):
 	"""Represents a tool that might be used by raptor e.g. a compiler"""
 
+	# It's difficult and expensive to give each tool a log reference but a class one
+	# will facilitate debugging when that is needed without being a design flaw the
+	# rest of the time.
+	log = raptor_utilities.nulllog
+
 	# For use in dealing with tools that return non-ascii version strings.
 	nonascii = ""
 	identity_chartable = chr(0)
@@ -1084,7 +1052,7 @@
 		nonascii += chr(c)
 		identity_chartable += " "
 
-	def __init__(self, name, command, versioncommand, versionresult, id="", log = raptor_utilities.nulllog):
+	def __init__(self, name, command, versioncommand, versionresult, id=""):
 		self.name = name
 		self.command = command
 		self.versioncommand = versioncommand
@@ -1097,7 +1065,6 @@
 		# version until someone proves that it's OK
 		self.valid = False
 
-		self.log=log
 
 	def expand(self, toolset):
 		self.versioncommand = toolset.ExpandAll(self.versioncommand)
@@ -1117,7 +1084,7 @@
 				# If it really is not a simple command then we won't be able to get a date and
 				# we won't be able to tell if it is altered or updated - too bad!
 				testfile = generic_path.Where(self.command)
-				self.log.Debug("toolcheck: tool '%s' was found on the path at '%s' ", self.command, testfile)
+				#self.log.Debug("toolcheck: tool '%s' was found on the path at '%s' ", self.command, testfile)
 				if testfile is None:
 					raise Exception("Can't be found in path")
 
@@ -1127,18 +1094,20 @@
 			testfile_stat = os.stat(testfile)
 			self.date = testfile_stat.st_mtime
 		except Exception,e:
-			self.log.Debug("toolcheck: '%s=%s' cannot be dated - this is ok, but the toolcheck won't be able to tell when a new  of the tool is installed. (%s)", self.name, self.command, str(e))
+			# We really don't mind if the tool could not be dated - for any reason
+			Tool.log.Debug("toolcheck: '%s=%s' cannot be dated - this is ok, but the toolcheck won't be able to tell when a new version of the tool is installed. (%s)", self.name, self.command, str(e))
+			pass
 	
 			
-	def check(self, shell, evaluator):
+	def check(self, shell, evaluator, log = raptor_utilities.nulllog):
 
 		self.vre = re.compile(self.versionresult)
 
 		try:
 			self.log.Debug("Pre toolcheck: '%s' for version '%s'", self.name, self.versionresult)
 			p = subprocess.Popen(args=[shell, "-c", self.versioncommand], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+			log.Debug("Checking tool '%s' for version '%s'", self.name, self.versionresult)
 			versionoutput,err = p.communicate()
-			self.log.Debug("Checking tool '%s' for version '%s'", self.name, self.versionresult)
 		except Exception,e:
 			versionoutput=None
 
@@ -1148,12 +1117,11 @@
 		versionoutput_a = versionoutput.translate(Tool.identity_chartable,"")
 
 		if versionoutput_a and self.vre.search(versionoutput_a) != None:
-			self.log.Debug("tool '%s' returned an acceptable version '%s' at %s", self.name, versionoutput_a, str(self.date))
+			log.Debug("tool '%s' returned an acceptable version '%s'", self.name, versionoutput_a)
 			self.valid = True
 		else:
-			self.log.Error("tool '%s' from config '%s' did not return version '%s' as required.\nCommand '%s' returned:\n%s\nCheck your environment and configuration.\n", self.name, self.id, self.versionresult, self.versioncommand, versionoutput_a)
 			self.valid = False
-		return self.valid
+			raise ToolErrorException("tool '%s' from config '%s' did not return version '%s' as required.\nCommand '%s' returned:\n%s\nCheck your environment and configuration.\n" % (self.name, self.id, self.versionresult, self.versioncommand, versionoutput_a))
 
 def envhash(irrelevant_vars):
 	"""Determine something unique about this environment to identify it.
@@ -1175,16 +1143,19 @@
 	write() is used to flush the cache to disc.
 	"""
 	# The raptor shell - this is not mutable.
-	hostbinaries = os.path.join(os.environ['SBS_HOME'], 
-	                            os.environ['HOSTPLATFORM_DIR'])
+	if 'SBS_SHELL' in os.environ:
+		shell = os.environ['SBS_SHELL']
+	else:
+		hostbinaries = os.path.join(os.environ['SBS_HOME'], 
+	                                os.environ['HOSTPLATFORM_DIR'])
 	                            
-	if HostPlatform.IsHost('lin*'):
-		shell=os.path.join(hostbinaries, 'bin/bash')
-	else:
-		if 'SBS_CYGWIN' in os.environ:
-			shell=os.path.join(os.environ['SBS_CYGWIN'], 'bin\\bash.exe')
+		if HostPlatform.IsHost('lin*'):
+			shell=os.path.join(hostbinaries, 'bin/bash')
 		else:
-			shell=os.path.join(hostbinaries, 'cygwin\\bin\\bash.exe')
+			if 'SBS_CYGWIN' in os.environ:
+				shell=os.path.join(os.environ['SBS_CYGWIN'], 'bin\\bash.exe')
+			else:
+				shell=os.path.join(hostbinaries, 'cygwin\\bin\\bash.exe')
 
 
 	irrelevant_vars = ['PWD','OLDPWD','PID','PPID', 'SHLVL' ]
@@ -1255,7 +1226,6 @@
 							except Exception, e:
 								log.Info("Ignoring garbled toolcheck cache: %s (%s)\n", self.cachefilename, str(e))
 								self.__toolcheckcache = {}
-								
 									
 						else:
 							log.Info("Toolcheck cache %s ignored - environment changed\n", self.cachefilename)
@@ -1316,8 +1286,11 @@
 
 			self.log.Debug("toolcheck done: %s -key: %s" % (tool.name, tool.key))
 
-			if not tool.check(ToolSet.shell, evaluator):
+			try:
+				tool.check(ToolSet.shell, evaluator, log = self.log)
+			except ToolErrorException, e:
 				self.valid = False
+				self.log.Error("%s\n" % str(e))
 
 			# Tool failures are cached just like successes - don't want to repeat them
 			cache[tool.key] =  { "name" : tool.name, "valid" : tool.valid, "age" : 0 , "date" : tool.date }
@@ -1356,6 +1329,8 @@
 				self.log.Info("Could not write toolcheck cache: %s", str(e))
 		return self.valid
 
+class UninitialisedVariableException(Exception):
+	pass
 
 class Evaluator(object):
 	"""Determine the values of variables under different Configurations.
@@ -1364,11 +1339,11 @@
 
 	refRegex = re.compile("\$\((.+?)\)")
 
-	def __init__(self, Raptor, specification, buildUnit, gathertools = False):
-		self.raptor = Raptor
+	def __init__(self, specification, buildUnit, cache, gathertools = False):
 		self.dict = {}
 		self.tools = []
 		self.gathertools = gathertools
+		self.cache = cache
 
 		specName = "none"
 		configName = "none"
@@ -1377,14 +1352,18 @@
 		opsLists = []
 
 		if buildUnit:
-			opsLists.extend( buildUnit.GetOperations() )
+			ol = buildUnit.GetOperations(cache)
+			self.buildUnit = buildUnit
+			
+			opsLists.extend( ol )
 
 		if specification:
-			for v in specification.GetAllVariantsRecursively():
-				opsLists.extend( v.GetAllOperationsRecursively() )
+			for v in specification.GetAllVariantsRecursively(cache):
+				opsLists.extend( v.GetAllOperationsRecursively(cache) )
 
 		tools = {}
 
+		unfound_values = []
 		for opsList in opsLists:
 			for op in opsList:
 				# applying an Operation to a non-existent variable
@@ -1394,13 +1373,20 @@
 				except KeyError:
 					oldValue = ""
 
-				newValue = op.Apply(oldValue)
+				try:
+					newValue = op.Apply(oldValue)
+				except BadToolValue, e:
+					unfound_values.append(str(e))
+					newValue = "NO_VALUE_FOR_" + op.name
+					
 				self.dict[op.name] = newValue
 			
 				if self.gathertools:
 					if op.type == "tool" and op.versionCommand and op.versionResult:
-						tools[op.name] = Tool(op.name, newValue, op.versionCommand, op.versionResult, configName, log = self.raptor)
+						tools[op.name] = Tool(op.name, newValue, op.versionCommand, op.versionResult, configName)
 
+		if len(unfound_values) > 0:
+			raise UninitialisedVariableException("\n".join(unfound_values))
 
 		if self.gathertools:
 			self.tools = tools.values()
@@ -1417,8 +1403,8 @@
 			unresolved = False
 			for k, v in self.dict.items():
 				if v.find('$(' + k + ')') != -1:
-					self.raptor.Error("Recursion Detected in variable '%s' in configuration '%s' ",k,configName)
-					expanded = "RECURSIVE_INVALID_STRING"
+						raise RecursionException("Recursion Detected in variable '%s' in configuration '%s' " % (k,configName))
+						expanded = "RECURSIVE_INVALID_STRING"
 				else:
 					expanded = self.ExpandAll(v, specName, configName)
 
@@ -1466,20 +1452,24 @@
 
 		refs = Evaluator.refRegex.findall(value)
 
+		# store up all the unset variables before raising an exception
+		# to allow us to find them all
+		unset_variables = [] 
+
 		for r in set(refs):
 			expansion = None
 
-			if r in self.raptor.override:
-				expansion = self.raptor.override[r]
-			elif r in self.dict:
+			if r in self.dict:
 				expansion = self.dict[r]
 			else:
 				# no expansion for $(r)
-				self.raptor.Error("Unset variable '%s' used in spec '%s' with config '%s'",
-							  	  r, spec, config)
+				unset_variables.append("Unset variable '%s' used in spec '%s' with config '%s'" % (r, spec, config))
 			if expansion != None:
 				value = value.replace("$(" + r + ")", expansion)
 
+		if len(unset_variables) > 0: # raise them all
+			raise UninitialisedVariableException(". ".join(unset_variables))
+
 		return value
 
 
--- a/sbsv2/raptor/python/raptor_make.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_make.py	Mon Nov 16 20:39:37 2009 +0000
@@ -20,13 +20,16 @@
 import os
 import random
 import raptor
-import raptor_data
 import raptor_utilities
 import raptor_version
+import raptor_data
 import re
 import subprocess
 import time
 from raptor_makefile import *
+import raptor_version
+import traceback
+import sys
 
 # raptor_make module classes
 
@@ -35,7 +38,6 @@
 	def __init__(self, Raptor):
 		self.raptor = Raptor
 		self.valid = True
-		self.makefileset = None
 		self.descrambler = None
 		self.descrambler_started = False
 
@@ -53,7 +55,7 @@
 					
 		# find the variant and extract the values
 		try:
-			units = avar.GenerateBuildUnits()
+			units = avar.GenerateBuildUnits(Raptor.cache)
 			evaluator = Raptor.GetEvaluator( None, units[0] , gathertools=True)
 
 			# shell
@@ -123,7 +125,7 @@
  component='$$COMPONENT_NAME'\
  bldinf='$$COMPONENT_META' mmp='$$PROJECT_META'\
  config='$$SBS_CONFIGURATION' platform='$$PLATFORM'\
- phase='$$MAKEFILE_GROUP' source='$$SOURCE
+ phase='$$MAKEFILE_GROUP' source='$$SOURCE'
 export TALON_RECIPEATTRIBUTES TALON_SHELL TALON_TIMEOUT
 USE_TALON:=%s
 
@@ -148,7 +150,7 @@
 
 include %s
 
-""" 		% (  raptor.name, raptor_version.Version(),
+""" 		% (  raptor.name, raptor_version.fullversion(),
 			 " ".join(raptor.hostplatform),
 			 raptor.hostplatform_dir,
 			 self.raptor.filesystem,
@@ -168,14 +170,17 @@
 		"""Generate a set of makefiles, or one big Makefile."""
 
 		if not self.valid:
-			return
+			return None
+
+		self.raptor.Debug("Writing Makefile '%s'" % (str(toplevel)))
 
 		self.toplevel = toplevel
 
 		# create the top-level makefiles
+		makefileset = None
 
 		try:
-			self.makefileset = MakefileSet(directory = str(toplevel.Dir()),
+			makefileset = MakefileSet(directory = str(toplevel.Dir()),
 										   selectors = self.selectors,
 										   filenamebase = str(toplevel.File()),
 										   prologue = self.makefile_prologue,
@@ -190,11 +195,10 @@
 			self.many = not self.raptor.writeSingleMakefile
 
 			# add a makefile for each spec under each config
-			config_makefileset = self.makefileset
-
+			config_makefileset = makefileset
 			for c in configs:
 				if self.many:
-					config_makefileset = self.makefileset.createChild(c.name)
+					config_makefileset = makefileset.createChild(c.name)
 
 				# make sure the config_wide spec item is put out first so that it
 				# can affect everything.
@@ -207,16 +211,22 @@
 						ordered_specs.append(s)
 
 				if config_wide_spec is not None:
-					config_wide_spec.Configure(c)
+					config_wide_spec.Configure(c, cache = self.raptor.cache)
 					self.WriteConfiguredSpec(config_makefileset, config_wide_spec, c, True)
 
 				for s in ordered_specs:
-					s.Configure(c)
+					s.Configure(c, cache = self.raptor.cache)
 					self.WriteConfiguredSpec(config_makefileset, s, c, False)
 
-			self.makefileset.close()
+			makefileset.close()
 		except Exception,e:
-			self.raptor.Error("Failed to write makefile '%s': %s" % (str(toplevel),str(e)))
+			tb = traceback.format_exc()
+			if not self.raptor.debugOutput:
+				tb=""
+			self.raptor.Error("Failed to write makefile '%s': %s : %s" % (str(toplevel),str(e),tb))
+			makefileset = None
+
+		return makefileset
 
 
 	def WriteConfiguredSpec(self, parentMakefileSet, spec, config, useAllInterfaces):
@@ -233,9 +243,10 @@
 		guard = None
 		if hasInterface:
 			# find the Interface (it may be a ref)
-			iface = spec.GetInterface()
+			try:
+				iface = spec.GetInterface(self.raptor.cache)
 
-			if iface == None:
+			except raptor_data.MissingInterfaceError, e:	
 				self.raptor.Error("No interface for '%s'", spec.name)
 				return
 
@@ -268,12 +279,12 @@
 				md5hash.update(value)
 
 			# parameters required by the interface
-			for p in iface.GetParams():
+			for p in iface.GetParams(self.raptor.cache):
 				val = evaluator.Resolve(p.name)
 				addparam(p.name,val,p.default)
 
 			# Use Patterns to fetch a group of parameters
-			for g in iface.GetParamGroups():
+			for g in iface.GetParamGroups(self.raptor.cache):
 				for k,v in evaluator.ResolveMatching(g.patternre):
 					addparam(k,v,g.default)
 
@@ -301,7 +312,7 @@
 
 		# generate the call to the FLM
 		if iface is not None:
-			makefileset.addCall(spec.name, config.name, iface.name, useAllInterfaces, iface.GetFLMIncludePath(), parameters, guard)
+			makefileset.addCall(spec.name, config.name, iface.name, useAllInterfaces, iface.GetFLMIncludePath(self.raptor.cache), parameters, guard)
 
 		# recursive includes
 
@@ -341,7 +352,7 @@
 				return False
 
 		# Save file names to a list, to allow the order to be reversed
-		fileName_list = list(self.makefileset.makefileNames())
+		fileName_list = list(makefileset.makefileNames())
 
 		# Iterate through args passed to raptor, searching for CLEAN or REALLYCLEAN
 		clean_flag = False
@@ -401,7 +412,7 @@
 
 			# targets go at the end, if the makefile supports them
 			addTargets = self.raptor.targets[:]
-			ignoreTargets = self.makefileset.ignoreTargets(makefile)
+			ignoreTargets = makefileset.ignoreTargets(makefile)
 			if addTargets and ignoreTargets:
 				for target in self.raptor.targets:
 					if re.match(ignoreTargets, target):
@@ -410,6 +421,9 @@
 			if addTargets:
 				command += " " + " ".join(addTargets)
 
+			# Substitute the makefile name for any occurrence of #MAKEFILE#
+			command = command.replace("#MAKEFILE#", str(makefile))
+
 			self.raptor.Info("Executing '%s'", command)
 
 			# execute the build.
@@ -496,7 +510,7 @@
 			looking = (os.system(command) != 0)
 			tries += 1
 		if looking:
-			self.raptor.Error("Failed to initilaise the talon shell for this build")
+			self.raptor.Error("Failed to initialise the talon shell for this build")
 			self.talonctl = ""
 			return False
 		
--- a/sbsv2/raptor/python/raptor_makefile.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_makefile.py	Mon Nov 16 20:39:37 2009 +0000
@@ -134,6 +134,15 @@
 
 		return True
 
+	def addInclude(self, makefilename):
+		"""
+		"""
+		# create the directory if it does not exist
+
+		self.open()
+		# now we can write the values into the makefile
+		self.file.write("include %s\n" % (makefilename+"."+self.selector.name))
+
 	def close(self):
 		if self.file is not None:
 			if self.epilogue != None:
@@ -191,6 +200,11 @@
 		for f in self.makefiles:
 			f.addCall(specname, configname, ifname, useAllInterfaces, flmpath, parameters, guard)
 
+	def addInclude(self, makefilename):
+		"""include a makefile from each of the makefiles in the set - has the selector name appended to it."""
+		for f in self.makefiles:
+			f.addInclude(makefilename)
+
 	def makefileNames(self):
 		for mf in self.makefiles:
 			yield str(mf.filename)
--- a/sbsv2/raptor/python/raptor_meta.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_meta.py	Mon Nov 16 20:39:37 2009 +0000
@@ -232,6 +232,19 @@
 	return commentDetail
 
 
+def getSpecName(aFileRoot, fullPath=False):
+	"""Returns a build spec name: this is the file root (full path
+	or simple file name) made safe for use as a file name."""
+
+	if fullPath:
+		specName = str(aFileRoot).replace("/","_")
+		specName = specName.replace(":","")
+	else:
+		specName = aFileRoot.File()
+
+	return specName.lower()
+
+
 # Classes
 
 class MetaDataError(Exception):
@@ -398,11 +411,13 @@
 	on the selected build platform.  This class provides a generic means of wrapping
 	up the preprocessing of such files."""
 
-	def __init__(self, aFilename, gnucpp, aRootLocation=None, log=None):
+	def __init__(self, aFilename, gnucpp, depfiles, aRootLocation=None, log=None):
 		"""
 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
 		@param aDefaultPlatform  Default preprocessed version of this file
 		@param aCPP 		location of GNU CPP
+		@param depfiles     	list to add dependency file tuples to
+		@param aRootLocation    where the file is 
 		@param log 		A class with Debug(<string>), Info(<string>) and Error(<string>) methods
 		"""
 		self.filename = aFilename
@@ -410,6 +425,7 @@
 		# Dictionary with key of build platform and a text string of processed output as values
 		self.__PreProcessedContent = {}
 		self.log = log
+		self.depfiles = depfiles
 
 		self.__gnucpp = gnucpp
 		if gnucpp is None:
@@ -436,7 +452,7 @@
 			else:
 				metatarget = "'$(PARSETARGET)'"
 			generateDepsOptions = "-MD -MF%s -MT%s" % (adepfilename, metatarget)
-			aBuildPlatform['METADEPS'].append((adepfilename, metatarget))
+			self.depfiles.append((adepfilename, metatarget))
 			try:
 				os.makedirs(os.path.dirname(adepfilename))
 			except Exception, e:
@@ -515,15 +531,17 @@
 	on the selected build platform.  This class provides a generic means of wrapping
 	up the preprocessing of such files."""
 
-	def __init__(self, aFilename, gnucpp, bldinf, log=None):
+	def __init__(self, aFilename, gnucpp, bldinf, depfiles, log=None):
 		"""
 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
 		@param gnucpp 		location of GNU CPP
-		@param bldinf   	the bldinf file that this mmp comes from
-		@param log 			A class with Debug(<string>), Info(<string>) and Error(<string>) methods
+		@param bldinf		the bld.inf file this mmp was specified in
+		@param depfiles         list to fill with mmp dependency files
+		@param log 		A class with Debug(<string>), Info(<string>) and Error(<string>) methods
 		"""
-		super(MMPFile, self).__init__(aFilename, gnucpp, str(bldinf.filename.Dir()), log)
+		super(MMPFile, self).__init__(aFilename, gnucpp, depfiles, str(bldinf.filename.Dir()),  log)
 		self.__bldinf = bldinf
+		self.depfiles = depfiles
 
 		self.__gnucpp = gnucpp
 		if gnucpp is None:
@@ -878,8 +896,8 @@
 class BldInfFile(MetaDataFile):
 	"""Representation of a Symbian bld.inf file"""
 
-	def __init__(self, aFilename, gnucpp, log=None):
-		MetaDataFile.__init__(self, aFilename, gnucpp, None, log)
+	def __init__(self, aFilename, gnucpp, depfiles, log=None):
+		MetaDataFile.__init__(self, aFilename, gnucpp, depfiles, None, log)
 		self.__Raptor = log
 		self.testManual = 0
 		self.testAuto = 0
@@ -1194,7 +1212,8 @@
 		super(MMPRaptorBackend,self).__init__()
 		self.platformblock = None
 		self.__Raptor = aRaptor
-		self.BuildVariant = raptor_data.Variant()
+		self.__debug("-----+++++ %s " % aMmpfilename)
+		self.BuildVariant = raptor_data.Variant(name = "mmp")
 		self.ResourceVariants = []
 		self.BitmapVariants = []
 		self.StringTableVariants = []
@@ -1208,11 +1227,11 @@
 		self.__systeminclude = ""
 		self.__bitmapSourcepath = self.__sourcepath
 		self.__current_resource = ""
-		self.__capabilities = []
-		self.__resourceFiles = []
 		self.__pageConflict = []
 		self.__debuggable = ""
+		self.__resourceFiles = []
 		self.sources = []
+		self.capabilities = []
 
 		self.__TARGET = ""
 		self.__TARGETEXT = ""
@@ -1423,9 +1442,8 @@
 
 		elif varname=='CAPABILITY':
 			for cap in toks[1]:
-				self.BuildVariant.AddOperation(raptor_data.Append(varname,cap," "))
 				self.__debug("Setting  "+toks[0]+": " + cap)
-				self.__capabilities.append(cap.lower())
+				self.capabilities.append(cap)
 		elif varname=='DEFFILE':
 			self.__defFileRoot = self.__currentMmpFile
 			self.deffile = toks[1]
@@ -1767,7 +1785,7 @@
 					replace = ""
 					if len(matches):
 						replace = matches.pop()
-					
+
 					searchReplacePairs.append('%s<->%s' % (search, replace))
 
 			# Replace spaces to maintain word-based grouping in downstream makefile lists
@@ -1886,7 +1904,7 @@
 		self.__currentLineNumber += 1
 		self.__debug("Start BITMAP "+toks[1])
 
-		self.__currentBitmapVariant = raptor_data.Variant(toks[1].replace('.','_'))
+		self.__currentBitmapVariant = raptor_data.Variant(name = toks[1].replace('.','_'))
 		# Use BMTARGET and BMTARGET_lower because that prevents
 		# confusion with the TARGET and TARGET_lower of our parent MMP
 		# when setting the OUTPUTPATH.  This in turn allows us to
@@ -1976,7 +1994,7 @@
 		self.__debug("stringtable: " + toks[1])
 		self.__debug("adjusted stringtable source=" + source)
 
-		self.__currentStringTableVariant = raptor_data.Variant(uniqname)
+		self.__currentStringTableVariant = raptor_data.Variant(name = uniqname)
 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source))
 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", ""))
 		self.__stringtableExported = False
@@ -2169,11 +2187,14 @@
 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_TARGET_lower", self.__TARGET.lower()))
 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_REQUESTEDTARGETEXT", self.__TARGETEXT.lower()))
 
+		# Create Capability variable in one SET operation (more efficient than multiple appends)
+		self.BuildVariant.AddOperation(raptor_data.Set("CAPABILITY"," ".join(self.capabilities)))
+
 		# Resolve combined capabilities as hex flags, for configurations that require them
 		capabilityFlag1 = 0
 		capabilityFlag2 = 0			# Always 0
 
-		for capability in self.__capabilities:
+		for capability in [c.lower() for c in self.capabilities]:
 			invert = 0
 
 			if capability.startswith('-'):
@@ -2285,6 +2306,32 @@
 		return resolvedDefFile
 
 
+def CheckedGet(self, key, default = None):
+	"""extract a value from an self and raise an exception if None.
+
+	An optional default can be set to replace a None value.
+
+	This function belongs in the Evaluator class logically. But
+	Evaluator doesn't know how to raise a Metadata error. Since
+	being able to raise a metadata error is the whole point of
+	the method, it makes sense to adapt the Evaluator class from
+	raptor_meta for the use of everything inside raptor_meta.
+
+	... so it will be added to the Evaluator class.
+	"""
+
+	value = self.Get(key)
+	if value == None:
+		if default == None:
+			raise MetaDataError("configuration " + self.buildUnit.name +
+							    " has no variable " + key)
+		else:
+			return default
+	return value
+
+raptor_data.Evaluator.CheckedGet = CheckedGet 
+
+
 class MetaReader(object):
 	"""Entry point class for Symbian metadata processing.
 
@@ -2301,10 +2348,10 @@
 		# Get the version of CPP that we are using
 		metadata = self.__Raptor.cache.FindNamedVariant("meta")
 		evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) )
-		self.__gnucpp = self.CheckValue(evaluator, "GNUCPP")
-		self.__defaultplatforms = self.CheckValue(evaluator, "DEFAULT_PLATFORMS")
-		self.__basedefaultplatforms = self.CheckValue(evaluator, "BASE_DEFAULT_PLATFORMS")
-		self.__baseuserdefaultplatforms = self.CheckValue(evaluator, "BASE_USER_DEFAULT_PLATFORMS")
+		self.__gnucpp = evaluator.CheckedGet("GNUCPP")
+		self.__defaultplatforms = evaluator.CheckedGet("DEFAULT_PLATFORMS")
+		self.__basedefaultplatforms = evaluator.CheckedGet("BASE_DEFAULT_PLATFORMS")
+		self.__baseuserdefaultplatforms = evaluator.CheckedGet("BASE_USER_DEFAULT_PLATFORMS")
 
 		# Only read each variant.cfg once
 		variantCfgs = {}
@@ -2323,24 +2370,25 @@
 		# with the same "export platform".
 		exports = {}
 
+		self.__Raptor.Debug("MetaReader: configsToBuild:  %s", [b.name for b in configsToBuild])
 		for buildConfig in configsToBuild:
 			# get everything we need to know about the configuration
 			evaluator = self.__Raptor.GetEvaluator(None, buildConfig)
 
 			detail = {}
-			detail['PLATFORM'] = self.CheckValue(evaluator, "TRADITIONAL_PLATFORM")
-			epocroot = self.CheckValue(evaluator, "EPOCROOT")
+			detail['PLATFORM'] = evaluator.CheckedGet("TRADITIONAL_PLATFORM")
+			epocroot = evaluator.CheckedGet("EPOCROOT")
 			detail['EPOCROOT'] = generic_path.Path(epocroot)
 
-			sbs_build_dir = self.CheckValue(evaluator, "SBS_BUILD_DIR")
+			sbs_build_dir = evaluator.CheckedGet("SBS_BUILD_DIR")
 			detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir)
-			flm_export_dir = self.CheckValue(evaluator, "FLM_EXPORT_DIR")
+			flm_export_dir = evaluator.CheckedGet("FLM_EXPORT_DIR")
 			detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir)
 			detail['CACHEID'] = flm_export_dir
 			if raptor_utilities.getOSPlatform().startswith("win"):
-				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.WINDOWS")
+				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.WINDOWS")
 			else:
-				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.LINUX")
+				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.LINUX")
 
 			# Apply OS variant provided we are not ignoring this
 			if not self.__Raptor.ignoreOsDetection:
@@ -2352,11 +2400,11 @@
 			# is this a feature variant config or an ordinary variant
 			fv = evaluator.Get("FEATUREVARIANTNAME")
 			if fv:
-				variantHdr = self.CheckValue(evaluator, "VARIANT_HRH")
+				variantHdr = evaluator.CheckedGet("VARIANT_HRH")
 				variantHRH = generic_path.Path(variantHdr)
 				detail['ISFEATUREVARIANT'] = True
 			else:
-				variantCfg = self.CheckValue(evaluator, "VARIANT_CFG")
+				variantCfg = evaluator.CheckedGet("VARIANT_CFG")
 				variantCfg = generic_path.Path(variantCfg)
 				if not variantCfg in variantCfgs:
 					# get VARIANT_HRH from the variant.cfg file
@@ -2371,19 +2419,18 @@
 
 			detail['VARIANT_HRH'] = variantHRH
 			self.__Raptor.Info("'%s' uses variant hrh file '%s'", buildConfig.name, variantHRH)
-			detail['SYSTEMINCLUDE'] = self.CheckValue(evaluator, "SYSTEMINCLUDE")
-
-			detail['METADEPS'] = [] # Dependency targets for all metadata files in this platform
+			detail['SYSTEMINCLUDE'] = evaluator.CheckedGet("SYSTEMINCLUDE")
+
 
 			# find all the interface names we need
-			ifaceTypes = self.CheckValue(evaluator, "INTERFACE_TYPES")
+			ifaceTypes = evaluator.CheckedGet("INTERFACE_TYPES")
 			interfaces = ifaceTypes.split()
 
 			for iface in interfaces:
-				detail[iface] = self.CheckValue(evaluator, "INTERFACE." + iface)
+				detail[iface] = evaluator.CheckedGet("INTERFACE." + iface)
 
 			# not test code unless positively specified
-			detail['TESTCODE'] = self.CheckValue(evaluator, "TESTCODE", "")
+			detail['TESTCODE'] = evaluator.CheckedGet("TESTCODE", "")
 
 			# make a key that identifies this platform uniquely
 			# - used to tell us whether we have done the pre-processing
@@ -2454,20 +2501,8 @@
 		# that are supposedly platform independent (e.g. PRJ_PLATFORMS)
 		self.defaultPlatform = self.ExportPlatforms[0]
 
-	def CheckValue(self, evaluator, key, default = None):
-		"""extract a value from an evaluator and raise an exception if None.
-
-		An optional default can be set to replace a None value."""
-		value = evaluator.Get(key)
-		if value == None:
-			if default == None:
-				raise MetaDataError("configuration " + evaluator.config.name +
-								    " has no variable " + key)
-			else:
-				return default
-		return value
-
-	def ReadBldInfFiles(self, aFileList, doExportOnly):
+
+	def ReadBldInfFiles(self, aComponentList, doExportOnly):
 		"""Take a list of bld.inf files and return a list of build specs.
 
 		The returned specification nodes will be suitable for all the build
@@ -2477,7 +2512,7 @@
 		# we need a Filter node per export platform
 		exportNodes = []
 		for i,ep in enumerate(self.ExportPlatforms):
-			filter = raptor_data.Filter("export_" + str(i))
+			filter = raptor_data.Filter(name = "export_" + str(i))
 
 			# what configurations is this node active for?
 			for config in ep['configs']:
@@ -2488,7 +2523,7 @@
 		# we need a Filter node per build platform
 		platformNodes = []
 		for i,bp in enumerate(self.BuildPlatforms):
-			filter = raptor_data.Filter("build_" + str(i))
+			filter = raptor_data.Filter(name = "build_" + str(i))
 
 			# what configurations is this node active for?
 			for config in bp['configs']:
@@ -2504,18 +2539,18 @@
 
 		# check that each bld.inf exists and add a Specification node for it
 		# to the nodes of the export and build platforms that it supports.
-		for bif in aFileList:
-			if bif.isFile():
-				self.__Raptor.Info("Processing %s", str(bif))
+		for c in aComponentList:
+			if c.bldinf_filename.isFile():
+				self.__Raptor.Info("Processing %s", str(c.bldinf_filename))
 				try:
-					self.AddComponentNodes(bif, exportNodes, platformNodes)
+					self.AddComponentNodes(c, exportNodes, platformNodes)
 
 				except MetaDataError, e:
-					self.__Raptor.Error(e.Text, bldinf=str(bif))
+					self.__Raptor.Error(e.Text, bldinf=str(c.bldinf_filename))
 					if not self.__Raptor.keepGoing:
 						return []
 			else:
-				self.__Raptor.Error("build info file does not exist", bldinf=str(bif))
+				self.__Raptor.Error("build info file does not exist", bldinf=str(c.bldinf_filename))
 				if not self.__Raptor.keepGoing:
 					return []
 
@@ -2617,74 +2652,78 @@
 		return moduleName
 
 
-	def AddComponentNodes(self, buildFile, exportNodes, platformNodes):
+	def AddComponentNodes(self, component, exportNodes, platformNodes):	
 		"""Add Specification nodes for a bld.inf to the appropriate platforms."""
-		bldInfFile = BldInfFile(buildFile, self.__gnucpp, self.__Raptor)
-
-		specName = self.getSpecName(buildFile, fullPath=True)
-
-		if isinstance(buildFile, raptor_xml.SystemModelComponent):
+		bldInfFile = BldInfFile(component.bldinf_filename, self.__gnucpp, component.depfiles, self.__Raptor)
+		component.bldinf = bldInfFile 
+
+		specName = getSpecName(component.bldinf_filename, fullPath=True)
+
+		if isinstance(component.bldinf, raptor_xml.SystemModelComponent):
 			# this component came from a system_definition.xml
-			layer = buildFile.GetContainerName("layer")
-			component = buildFile.GetContainerName("component")
+			layer = component.bldinf.GetContainerName("layer")
+			componentName = component.bldinf.GetContainerName("component")
 		else:
 			# this is a plain old bld.inf file from the command-line
 			layer = ""
-			component = ""
+			componentName = ""
 
 		# exports are independent of build platform
 		for i,ep in enumerate(self.ExportPlatforms):
-			specNode = raptor_data.Specification(specName)
+			specNode = raptor_data.Specification(name = specName)
 
 			# keep the BldInfFile object for later
-			specNode.bldinf = bldInfFile
+			specNode.component = component
 
 			# add some basic data in a component-wide variant
-			var = raptor_data.Variant()
-			var.AddOperation(raptor_data.Set("COMPONENT_META", str(buildFile)))
-			var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
+			var = raptor_data.Variant(name='component-wide')
+			var.AddOperation(raptor_data.Set("COMPONENT_META", str(component.bldinf_filename)))
+			var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
 			var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
 			specNode.AddVariant(var)
 
 			# add this bld.inf Specification to the export platform
 			exportNodes[i].AddChild(specNode)
+			component.exportspecs.append(specNode)
 
 		# get the relevant build platforms
 		listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform)
 		platforms = getBuildableBldInfBuildPlatforms(listedPlatforms,
-													self.__defaultplatforms,
-													self.__basedefaultplatforms,
-													self.__baseuserdefaultplatforms)
-
-
-
-		outputDir = BldInfFile.outputPathFragment(buildFile)
+								self.__defaultplatforms,
+								self.__basedefaultplatforms,
+								self.__baseuserdefaultplatforms)
+
+
+		outputDir = BldInfFile.outputPathFragment(component.bldinf_filename)
 
 		# Calculate "module name"
-		modulename = self.ModuleName(str(buildFile))
+		modulename = self.ModuleName(str(component.bldinf_filename))
 
 		for i,bp in enumerate(self.BuildPlatforms):
+			plat = bp['PLATFORM']
 			if bp['PLATFORM'] in platforms:
-				specNode = raptor_data.Specification(specName)
-
-				# keep the BldInfFile object for later
-				specNode.bldinf = bldInfFile
+				specNode = raptor_data.Specification(name = specName)
+
+				# remember what component this spec node comes from for later
+				specNode.component = component
 
 				# add some basic data in a component-wide variant
-				var = raptor_data.Variant()
-				var.AddOperation(raptor_data.Set("COMPONENT_META",str(buildFile)))
-				var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
+				var = raptor_data.Variant(name='component-wide-settings-' + plat)
+				var.AddOperation(raptor_data.Set("COMPONENT_META",str(component.bldinf_filename)))
+				var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
 				var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
 				var.AddOperation(raptor_data.Set("MODULE", modulename))
 				var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/'))
 				var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/'))
 				var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/'))
 
-				var.AddOperation(raptor_data.Set("TEST_OPTION", specNode.bldinf.getRomTestType(bp)))
+				var.AddOperation(raptor_data.Set("TEST_OPTION", component.bldinf.getRomTestType(bp)))
 				specNode.AddVariant(var)
 
 				# add this bld.inf Specification to the build platform
 				platformNodes[i].AddChild(specNode)
+				# also attach it into the component
+				component.specs.append(specNode)
 
 	def ProcessExports(self, componentNode, exportPlatform):
 		"""Do the exports for a given platform and skeleton bld.inf node.
@@ -2696,18 +2735,18 @@
 		[some MMP files #include exported .mmh files]
 		"""
 		if exportPlatform["TESTCODE"]:
-			exports = componentNode.bldinf.getTestExports(exportPlatform)
+			exports = componentNode.component.bldinf.getTestExports(exportPlatform)
 		else:
-			exports = componentNode.bldinf.getExports(exportPlatform)
+			exports = componentNode.component.bldinf.getExports(exportPlatform)
 
 		self.__Raptor.Debug("%i exports for %s",
-							len(exports), str(componentNode.bldinf.filename))
+							len(exports), str(componentNode.component.bldinf.filename))
 		if exports:
 
 			# each export is either a 'copy' or 'unzip'
 			# maybe we should trap multiple exports to the same location here?
 			epocroot = str(exportPlatform["EPOCROOT"])
-			bldinf_filename = str(componentNode.bldinf.filename)
+			bldinf_filename = str(componentNode.component.bldinf.filename)
 			exportwhatlog="<whatlog bldinf='%s' mmp='' config=''>\n" % bldinf_filename
 			for export in exports:
 				expSrc = export.getSource()
@@ -2730,7 +2769,6 @@
 							# export the file
 							exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename)
 						else:
-							# unzip the zip
 							exportwhatlog += ("<archive zipfile='" + str(fromFile) + "'>\n")
 							members = self.UnzipExport(fromFile, toFile,
 									str(exportPlatform['SBS_BUILD_DIR']),
@@ -2917,12 +2955,12 @@
 			return	# feature variation does not run extensions at all
 		
 		if buildPlatform["TESTCODE"]:
-			extensions = componentNode.bldinf.getTestExtensions(buildPlatform)
+			extensions = componentNode.component.bldinf.getTestExtensions(buildPlatform)
 		else:
-			extensions = componentNode.bldinf.getExtensions(buildPlatform)
+			extensions = componentNode.component.bldinf.getExtensions(buildPlatform)
 
 		self.__Raptor.Debug("%i template extension makefiles for %s",
-							len(extensions), str(componentNode.bldinf.filename))
+							len(extensions), str(componentNode.component.bldinf.filename))
 
 		for i,extension in enumerate(extensions):
 			if self.__Raptor.projects:
@@ -3001,14 +3039,20 @@
 		gnuList = []
 		makefileList = []
 
+
+		component = componentNode.component
+
+
 		if buildPlatform["TESTCODE"]:
-			MMPList = componentNode.bldinf.getTestMMPList(buildPlatform)
+			MMPList = component.bldinf.getTestMMPList(buildPlatform)
 		else:
-			MMPList = componentNode.bldinf.getMMPList(buildPlatform)
-
-		bldInfFile = componentNode.bldinf.filename
+			MMPList = component.bldinf.getMMPList(buildPlatform)
+
+		bldInfFile = component.bldinf.filename
 
 		for mmpFileEntry in MMPList['mmpFileList']:
+			component.AddMMP(mmpFileEntry.filename) # Tell the component another mmp is specified (for this platform)
+
 			projectname = mmpFileEntry.filename.File().lower()
 
 			if self.__Raptor.projects:
@@ -3026,7 +3070,8 @@
 
 			mmpFile = MMPFile(foundmmpfile,
 								   self.__gnucpp,
-								   bldinf = componentNode.bldinf,
+								   component.bldinf,
+								   component.depfiles,
 								   log = self.__Raptor)
 
 			mmpFilename = mmpFile.filename
@@ -3060,7 +3105,7 @@
 				continue
 			
 			# now build the specification tree
-			mmpSpec = raptor_data.Specification(self.getSpecName(mmpFilename))
+			mmpSpec = raptor_data.Specification(generic_path.Path(getSpecName(mmpFilename)))
 			var = backend.BuildVariant
 
 			var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename)))
@@ -3096,7 +3141,7 @@
 
 			# Although not part of the MMP, some MMP-based build specs additionally require knowledge of their
 			# container bld.inf exported headers
-			for export in componentNode.bldinf.getExports(buildPlatform):
+			for export in componentNode.component.bldinf.getExports(buildPlatform):
 				destination = export.getDestination()
 				if isinstance(destination, list):
 					exportfile = str(destination[0])
@@ -3152,7 +3197,7 @@
 					self.projectList.remove(projectname)
 
 			self.__Raptor.Debug("%i gnumakefile extension makefiles for %s",
-						len(gnuList), str(componentNode.bldinf.filename))
+						len(gnuList), str(componentNode.component.bldinf.filename))
 			var = raptor_data.Variant()
 			gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName()))
 			interface = buildPlatform["ext_makefile"]
@@ -3184,7 +3229,7 @@
 					projectList.remove(projectname)
 
 			self.__Raptor.Debug("%i makefile extension makefiles for %s",
-						len(makefileList), str(componentNode.bldinf.filename))
+						len(makefileList), str(componentNode.component.bldinf.filename))
 			var = raptor_data.Variant()
 			gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName()))
 			interface = buildPlatform["ext_makefile"]
@@ -3205,17 +3250,6 @@
 			gnuSpec.AddVariant(var)
 			componentNode.AddChild(gnuSpec)
 
-	def getSpecName(self, aFileRoot, fullPath=False):
-		"""Returns a build spec name: this is the file root (full path
-		or simple file name) made safe for use as a file name."""
-
-		if fullPath:
-			specName = str(aFileRoot).replace("/","_")
-			specName = specName.replace(":","")
-		else:
-			specName = aFileRoot.File()
-
-		return specName.lower()
 
 	def ApplyOSVariant(self, aBuildUnit, aEpocroot):
 		# Form path to kif.xml and path to buildinfo.txt
--- a/sbsv2/raptor/python/raptor_version.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/python/raptor_version.py	Mon Nov 16 20:39:37 2009 +0000
@@ -15,6 +15,12 @@
 # raptor version information module
 #
 
-def Version():
+version=(2,11,0,"2009-11-16","pp-preview")
+
+def numericversion():
 	"""Raptor version string"""
-	return "2.10.2 [2009-11-12 sf release]"
+	return "%d.%d.%d" % version[:3]
+
+def fullversion():
+	"""Raptor version string"""
+	return "%d.%d.%d [%s %s]" % version
--- a/sbsv2/raptor/test/common/raptor_tests.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/common/raptor_tests.py	Mon Nov 16 20:39:37 2009 +0000
@@ -179,6 +179,11 @@
 
 def fix_id(input_id):
 	return input_id.zfill(4)
+
+
+def grep(file, string):
+	return
+
 	
 # Test classes ################################################################
 
@@ -186,13 +191,15 @@
 	"""Base class for Smoke Test objects.
 	
 	Each test is defined (minimally) by,
-	1) a raptor command-line
-	2) a list of target files that should get built
+	1) an ID number as a string
+	2) a name
+	3) a raptor command-line
+	4) some parameters to check the command results against
 
 	The run() method will,
 	1) delete all the listed target files
 	2) execute the raptor command
-	3) check that the target files were created
+	3) check that the test results match the test parameters
 	4) count the warnings and errors reported
 	"""
 	
@@ -202,7 +209,7 @@
 
 	def __init__(self):
 		
-		self.id = 0
+		self.id = "0"
 		self.name = "smoketest"
 		self.description = ""
 		self.command = "sbs --do_what_i_want"
@@ -261,23 +268,24 @@
 			self.result = SmokeTest.FAIL
 		
 		# print the result of this run()
-		self.print_result(True)
+		self.print_result(internal = True)
 		
 		# if a previous run() failed then the overall result is a FAIL
 		if previousResult == SmokeTest.FAIL:
 			self.result = SmokeTest.FAIL
 	
-	def print_result(self, internal = False, value = ""):
+	def print_result(self, value = "", internal = False):
 		# the test passed :-)
 		
 		result = self.result
+			
+		string = ""
+		if not internal:
+			string += "\n" + self.name + ": "
 		
-		if value != "":
-			print value
+		if value:
+			print string + value
 		else:
-			string = ""
-			if not internal:
-				string += "\n" + self.name + ": "
 			if result == SmokeTest.PASS:
 				string += "PASSED"
 			elif result == SmokeTest.FAIL:
@@ -366,19 +374,27 @@
 		# Any environment settings specific to this test
 		shellenv = os.environ.copy()
 		for ev in self.environ:
-			shellenv[ev] = self.environ[ev]	
+			shellenv[ev] = self.environ[ev]
 
 		if self.usebash:
 			shellpath = shellenv['PATH']
+			
+			if 'SBS_SHELL' in os.environ:
+				BASH = os.environ['SBS_SHELL']
+			else:
+				if self.onWindows:
+					if 'SBS_CYGWIN' in shellenv:
+						BASH = ReplaceEnvs("$(SBS_CYGWIN)/bin/bash.exe")
+					else:
+						BASH = ReplaceEnvs("$(SBS_HOME)/win32/cygwin/bin/bash.exe")
+				else:
+					BASH = ReplaceEnvs("$(SBS_HOME)/$(HOSTPLATFORM_DIR)/bin/bash")
+				
 			if self.onWindows:
 				if 'SBS_CYGWIN' in shellenv:
 					shellpath = ReplaceEnvs("$(SBS_CYGWIN)/bin") + ";" + shellpath
-					BASH=ReplaceEnvs("$(SBS_CYGWIN)/bin/bash.exe")
 				else:
 					shellpath = ReplaceEnvs("$(SBS_HOME)/win32/cygwin/bin") + ";" + shellpath
-					BASH=ReplaceEnvs("$(SBS_HOME)/win32/cygwin/bin/bash.exe")
-			else:
-				BASH=ReplaceEnvs("$(SBS_HOME)/$(HOSTPLATFORM_DIR)/bin/bash")
 
 			shellenv['SBSMAKEFILE']=ReplaceEnvs(self.makefile())
 			shellenv['SBSLOGFILE']=ReplaceEnvs(self.logfile())
@@ -645,5 +661,6 @@
 			else:
 				self.antitargets.append(["$(EPOCROOT)/epoc32/build/"+fragment+"/"+x for x in t])
 		return
+
 	
 # the end
--- a/sbsv2/raptor/test/config/arm.xml	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/config/arm.xml	Mon Nov 16 20:39:37 2009 +0000
@@ -7,6 +7,7 @@
   <!-- build configurations for ARM compilers -->
 
   <var name="ARMV5_BASE">
+    <env name='SBS_HOME' default='' type='path'/>
     <env name='EPOCROOT'/>
     <env name='ARMROOT'/>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/test/retirement/metadep.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+from raptor_tests import SmokeTest
+
+def run():
+	t = SmokeTest()
+	t.id = "71"
+	t.name = "metadep"
+	t.description =  """Tests metadata dependency generation.  Changes 
+			to bld.infs and mmps can be detected."""
+	t.usebash = True
+	t.command = """export SBSLOGFILE SBSMAKEFILE; bash smoke_suite/test_resources/metadep.sh 2>&1"""
+			
+	t.targets = [
+		]
+
+	t.mustmatch_multiline = [
+""".*Step 1 .*no warnings or errors.*
+sbs: build log in.*
+\+ sleep 1.*
+.*make -rf .*epoc32/build/metadata_all.mk.*
+.*make.*epoc32/build/metadata_all.mk. is up to date.*
+Step 2 .*
+.*RE-RUNNING SBS with previous parameters.*
+Step 3 .*
+.*RE-RUNNING SBS with previous parameters.*
+.*RE-RUNNING SBS with previous parameters.*"""
+	]
+	t.mustnotmatch_multiline = [
+"""RE-RUNNING SBS with previous parameters.*
+RE-RUNNING SBS with previous parameters.*
+RE-RUNNING SBS with previous parameters.*
+RE-RUNNING SBS with previous parameters.*"""
+	]
+	t.run()
+	return t
--- a/sbsv2/raptor/test/smoke_suite/bitmap.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/smoke_suite/bitmap.py	Mon Nov 16 20:39:37 2009 +0000
@@ -40,10 +40,10 @@
 		"testbitmap_dll/testbitmap.mBm_bmconvcommands"
 	])
 	t.mustmatch = [
-		".*Makefile.bitmap:MIFCONV_TEST:=1.*"
+		".*Makefile(_all)?.bitmap:MIFCONV_TEST:=1.*"
 	]
 	t.mustnotmatch = [
-		".*Makefile.default:MIFCONV_TEST.*"
+		".*Makefile(_all)?.default:MIFCONV_TEST.*"
 	]
 	t.run()
 	return t
--- a/sbsv2/raptor/test/smoke_suite/clean_readonly.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/smoke_suite/clean_readonly.py	Mon Nov 16 20:39:37 2009 +0000
@@ -19,26 +19,54 @@
 import stat
 
 def run():
-	# This particular file createstaticdll.dll is changed to be readonly to test
-	# 		if sbs CLEAN command actually gets rid of read only files
-	fileForClean = (os.environ['EPOCROOT'] + \
-			"/epoc32/release/armv5/urel/createstaticdll.dll")
-	if os.path.exists(fileForClean):
-		os.chmod(fileForClean, stat.S_IREAD)
+	
+	# build something; make it read-only; then try and clean it
 	
 	t = AntiTargetSmokeTest()
-	t.id = "10"
+	t.id = "10a"
 	t.name = "cleanreadonly" 
-	t.command = "sbs -b smoke_suite/test_resources/simple_dll/bld.inf -c armv5 CLEAN"
-	t.antitargets = [
+	t.command = "sbs -b smoke_suite/test_resources/simple_dll/bld.inf -c armv5"
+	t.targets = [
 		"$(EPOCROOT)/epoc32/release/armv5/udeb/createstaticdll.dll.sym",
-		"$(EPOCROOT)/epoc32/build/test/simple_dll/createstaticdll_dll/armv5/udeb/CreateStaticDLL.o",
 		"$(EPOCROOT)/epoc32/release/armv5/urel/createstaticdll.dll.sym",
-		"$(EPOCROOT)/epoc32/build/test/simple_dll/createstaticdll_dll/armv5/urel/CreateStaticDLL.o",
 		"$(EPOCROOT)/epoc32/release/armv5/lib/createstaticdll.dso",
 		"$(EPOCROOT)/epoc32/release/armv5/lib/createstaticdll{000a0000}.dso",
 		"$(EPOCROOT)/epoc32/release/armv5/udeb/createstaticdll.dll",
 		"$(EPOCROOT)/epoc32/release/armv5/urel/createstaticdll.dll"
 	]
+	t.addbuildtargets("smoke_suite/test_resources/simple_dll/bld.inf",
+	[
+	"createstaticdll_dll/armv5/udeb/CreateStaticDLL.o",
+	"createstaticdll_dll/armv5/urel/CreateStaticDLL.o"
+	])
 	t.run()
+	setupOK = (t.result != AntiTargetSmokeTest.FAIL)
+	
+	# This particular file createstaticdll.dll is changed to be readonly to test
+	# 		if sbs CLEAN command actually gets rid of read only files
+	fileForClean = os.environ['EPOCROOT'] + "/epoc32/release/armv5/urel/createstaticdll.dll"
+	if os.path.exists(fileForClean):
+		os.chmod(fileForClean, stat.S_IREAD)
+	
+	t.id = "10"
+	t.command = "sbs -b smoke_suite/test_resources/simple_dll/bld.inf -c armv5 CLEAN"
+	t.targets = []
+	t.antitargets = [
+		"$(EPOCROOT)/epoc32/release/armv5/udeb/createstaticdll.dll.sym",
+		"$(EPOCROOT)/epoc32/release/armv5/urel/createstaticdll.dll.sym",
+		"$(EPOCROOT)/epoc32/release/armv5/lib/createstaticdll.dso",
+		"$(EPOCROOT)/epoc32/release/armv5/lib/createstaticdll{000a0000}.dso",
+		"$(EPOCROOT)/epoc32/release/armv5/udeb/createstaticdll.dll",
+		"$(EPOCROOT)/epoc32/release/armv5/urel/createstaticdll.dll"
+	]
+	t.addbuildantitargets("smoke_suite/test_resources/simple_dll/bld.inf",
+	[
+	"createstaticdll_dll/armv5/udeb/CreateStaticDLL.o",
+	"createstaticdll_dll/armv5/urel/CreateStaticDLL.o"
+	])
+	t.run()
+	
+	if not setupOK:
+		t.result = AntiTargetSmokeTest.FAIL
+		
 	return t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/test/smoke_suite/commandline.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,21 @@
+# General commandline option handling tests which aren't appropriate as unit tests.
+
+from raptor_tests import SmokeTest
+
+def run():
+	t = SmokeTest()
+	t.id = "91a"
+	t.name = "commandline_nodefaults"
+	t.description = """Test that raptor complains if you run it without specifying any components and there is no default bld.inf or system definition in the current directory."""
+	t.usebash = True
+			
+	t.command = """
+		TMPDIR="build/commandline_testdefaults";
+		cd $(EPOCROOT)/epoc32 && rm -rf "$TMPDIR" 2>/dev/null; mkdir -p "$TMPDIR" && cd "$TMPDIR" &&
+		sbs ${SBSLOGFILE} -n ; rm -rf "$TMPDIR"
+m	""" 
+		
+	t.mustmatch = [".*warning: No default bld.inf or system definition.*found.* "]
+	t.warnings = 1
+	t.result = t.run()
+	return t
--- a/sbsv2/raptor/test/smoke_suite/featurevariants.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/smoke_suite/featurevariants.py	Mon Nov 16 20:39:37 2009 +0000
@@ -15,6 +15,7 @@
 #
 
 from raptor_tests import SmokeTest
+import os
 
 def run():
 	t = SmokeTest()
@@ -228,9 +229,13 @@
 	createvmap = "python $(SBS_HOME)/bin/createvmap.py"
 	vmapfile = "$(EPOCROOT)/epoc32/build/test.vmap"
 	vmap = " -o " + vmapfile
-	bvcpp = " -c $(SBS_HOME)/$(HOSTPLATFORM_DIR)/bv/bin/cpp"
-	if t.onWindows:
-		bvcpp += ".exe"
+	
+	if 'SBS_BVCPP' in os.environ:
+		bvcpp = " -c " + os.environ['SBS_BVCPP']
+	else:
+		bvcpp = " -c $(SBS_HOME)/$(HOSTPLATFORM_DIR)/bv/bin/cpp"
+		if t.onWindows:
+			bvcpp += ".exe"
 
 	bvdata = "$(SBS_HOME)/test/smoke_suite/test_resources/bv"
 	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/test/smoke_suite/user_tools.py	Mon Nov 16 20:39:37 2009 +0000
@@ -0,0 +1,82 @@
+import os
+import sys
+from raptor_tests import SmokeTest
+
+def run():
+	
+	t = SmokeTest()
+	t.id = "86"
+	t.name = "user_tools"
+	
+	if sys.platform.lower().startswith("win"):
+		result = SmokeTest.PASS
+		t.logfileOption = lambda :""
+		t.makefileOption = lambda :""
+		t.description = "Tests that Raptor picks up SBS_PYTHON, SBS_CYGWIN " \
+				+ "and SBS_MINGW from the environment when present"
+		
+		
+		t.id = "0086a"
+		t.name = "user_python"
+		t.environ['SBS_PYTHON'] = "C:/pyt*hon"
+		
+		t.command = "sbs -b smoke_suite/test_resources/simple/bld.inf -c armv5_urel" \
+					+ " -n --toolcheck off -f " + t.logfile() + " -m " + t.makefile()
+				
+		t.mustmatch = [
+				"'C:/pyt\*hon' is not recognized as an internal or external command,",
+				"operable program or batch file."
+				]
+		t.returncode = 9009
+		t.run()
+		if t.result == SmokeTest.FAIL:
+			result = SmokeTest.FAIL
+	
+	
+		t.id = "0086b"
+		t.name = "user_cygwin"
+		t.environ = {}
+		t.environ['SBS_CYGWIN'] = "C:/cygwin"
+		
+		t.command = "sbs -b smoke_suite/test_resources/simple/bld.inf -c armv5_urel" \
+				+ " -n --toolcheck off -f " + t.logfile() + " -m " + t.makefile() \
+				+ " && $(__CYGWIN__)/bin/grep.exe -ir 'TALON_SHELL:=C:/cygwin/bin/sh.exe' " + t.makefile() + ".default"
+				
+		t.mustmatch = [
+				"TALON_SHELL:=C:/cygwin/bin/sh.exe"
+				]
+		t.returncode = 0
+		t.run()
+		if t.result == SmokeTest.FAIL:
+			result = SmokeTest.FAIL
+		
+		
+		t.id = "0086c"
+		t.name = "user_mingw"
+		t.environ = {}
+		t.environ['SBS_MINGW'] = "C:/mingw"
+		
+		t.command = "sbs -b smoke_suite/test_resources/simple/bld.inf -c armv5_urel" \
+				+ " -n --toolcheck off -f " + t.logfile() + " -m " + t.makefile()
+				
+		t.mustmatch = [
+				"sbs: error: Preprocessor exception: \[Error 3\] The system cannot find the path specified"
+				]
+		
+		t.errors = 1
+		t.returncode = 1
+		
+		t.run()
+		if t.result == SmokeTest.FAIL:
+			result = SmokeTest.FAIL
+		
+		t.id = "86"
+		t.name = "user_tools"
+		t.result = result
+		t.print_result()
+		
+	else:
+		t.run("windows")
+		
+		
+	return t
--- a/sbsv2/raptor/test/unit_suite/raptor_data_unit.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/unit_suite/raptor_data_unit.py	Mon Nov 16 20:39:37 2009 +0000
@@ -84,26 +84,26 @@
 		filter.AddChildSpecification(raptor_data.Specification("TrueSpec"))
 		filter.Else.AddChildSpecification(raptor_data.Specification("FalseSpec"))
 		
-		filter.Configure( raptor_data.BuildUnit("ARMV5",[]) )
+		filter.Configure( raptor_data.BuildUnit("ARMV5",[]), cache=None )
 		# check a positive test
-		iface = filter.GetInterface()
+		iface = filter.GetInterface(cache=None)
 		self.assertEqual(iface.name, "True.EXE")
-		vars = filter.GetVariants()
+		vars = filter.GetVariants(cache = None)
 		self.assertEqual(vars[0].name, "True_var")
 		kids = filter.GetChildSpecs()
 		self.assertEqual(kids[0].name, "TrueSpec")
 		
-		filter.Configure( raptor_data.BuildUnit("NOT_ARMV5",[]) )
+		filter.Configure( raptor_data.BuildUnit("NOT_ARMV5",[]) , cache = None)
 		# check a negative test
-		iface = filter.GetInterface()
+		iface = filter.GetInterface(cache = None)
 		self.assertEqual(iface.name, "False.EXE")
-		vars = filter.GetVariants()
+		vars = filter.GetVariants(cache = None)
 		self.assertEqual(vars[0].name, "False_var")
 		kids = filter.GetChildSpecs()
 		self.assertEqual(kids[0].name, "FalseSpec")
 		
 
-	def testSimpeVariant(self):
+	def testSimpleVariant(self):
 		var = raptor_data.Variant()
 		self.failUnless(var)
 		self.failIf( var.Valid() )
@@ -127,7 +127,7 @@
 		self.failUnless( var.Valid() )
 
 		var.SetProperty("extends", "")
-		ops = var.GetAllOperationsRecursively()
+		ops = var.GetAllOperationsRecursively(None)
 
 		self.assertEqual( len(ops), 1 )
 		self.assertEqual( len(ops[0]), 2 )
@@ -158,16 +158,16 @@
 		r.cache.AddVariant(varB)
 		r.cache.AddVariant(varC)
 
-		e = r.GetEvaluator(None, varA.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varA.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2A" )
 
-		e = r.GetEvaluator(None, varB.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varB.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2B" )
 		self.assertEqual( e.Get("V3"), "3B" )
 
-		e = r.GetEvaluator(None, varC.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varC.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2B" )
 		self.assertEqual( e.Get("V3"), "3C" )
@@ -201,15 +201,15 @@
 		r.cache.AddVariant(varB)
 		r.cache.AddVariant(varC)
 
-		e = r.GetEvaluator(None, varA.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varA.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2A" )
 
-		e = r.GetEvaluator(None, varC.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varC.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V3"), "3C" )
 		self.assertEqual( e.Get("V4"), "4C" )
 
-		e = r.GetEvaluator(None, varB.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, varB.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2B" )
 		self.assertEqual( e.Get("V3"), "3B" )
@@ -240,7 +240,7 @@
 
 		self.failUnless( alias.Valid() )
 
-		e = r.GetEvaluator(None, alias.GenerateBuildUnits()[0] )
+		e = r.GetEvaluator(None, alias.GenerateBuildUnits(r.cache)[0] )
 		self.assertEqual( e.Get("V1"), "1A" )
 		self.assertEqual( e.Get("V2"), "2B" )
 		self.assertEqual( e.Get("V3"), "3C" )
@@ -294,14 +294,14 @@
 		self.failUnless( group1.Valid() )
 		self.failUnless( group2.Valid() )
 
-		buildUnits = group1.GenerateBuildUnits()
+		buildUnits = group1.GenerateBuildUnits(r.cache)
 		self.assertEqual( len(buildUnits), 2 )
 		self.assertEqual( buildUnits[0].name, "A" )
 		self.assertEqual( buildUnits[1].name, "alias" )
 		self.assertEqual( buildUnits[1].variants[0].name, "B" )
 		self.assertEqual( buildUnits[1].variants[1].name, "C" )
 
-		buildUnits = group2.GenerateBuildUnits()
+		buildUnits = group2.GenerateBuildUnits(r.cache)
 		self.assertEqual( len(buildUnits), 3 )
 		self.assertEqual( buildUnits[0].name, "C.B" )
 		self.assertEqual( buildUnits[1].name, "A" )
@@ -316,7 +316,7 @@
 
 		r.cache.Load( generic_path.Join(r.home, "test", "config", "arm.xml") )
 
-		buildUnits = r.cache.FindNamedGroup("G2").GenerateBuildUnits()
+		buildUnits = r.cache.FindNamedGroup("G2").GenerateBuildUnits(r.cache)
 
 		self.assertEqual( len(buildUnits), 8 )
 
@@ -345,10 +345,11 @@
 		self.SetEnv("EPOCROOT", "/C")
 		aRaptor = raptor.Raptor()
 		cache = aRaptor.cache
+		aRaptor.debugOutput = True
 		cache.Load(generic_path.Join(aRaptor.home, "test", "config", "arm.xml"))
 		
 		var = cache.FindNamedVariant("ARMV5_UREL")
-		eval = aRaptor.GetEvaluator( None, var.GenerateBuildUnits()[0] )
+		eval = aRaptor.GetEvaluator( None, var.GenerateBuildUnits(aRaptor.cache)[0])
 		self.RestoreEnv("EPOCROOT")
 		
 		# test the Get method
@@ -366,13 +367,14 @@
 		var.AddOperation(raptor_data.Env("RAPTOR_SAYS_NO"))
 
 		aRaptor = raptor.Raptor()
-		var.SetOwner(aRaptor)
-		
-		eval = aRaptor.GetEvaluator(None, var.GenerateBuildUnits()[0] )
-		badval = eval.Get("RAPTOR_SAYS_NO")
-		
-		self.assertEqual(badval, "NO_VALUE_FOR_RAPTOR_SAYS_NO")
-		self.assertEqual(aRaptor.errorCode, 1)
+	
+		try:	
+			eval = aRaptor.GetEvaluator(None, var.GenerateBuildUnits(aRaptor.cache)[0] )
+			badval = eval.Get("RAPTOR_SAYS_NO")
+		except raptor_data.UninitialisedVariableException, e:
+			return
+
+		self.assertTrue(False)
 
 	def checkForParam(self, params, name, default):
 		for p in params:
@@ -386,27 +388,27 @@
 		cache.Load(generic_path.Join(aRaptor.home, "test", "config", "interface.xml"))
 		
 		base = cache.FindNamedInterface("Base.XYZ")
-		p = base.GetParams()
+		p = base.GetParams(cache)
 		self.failUnless(self.checkForParam(p, "A", None))
 		self.failUnless(self.checkForParam(p, "B", "baseB"))
 		self.failUnless(self.checkForParam(p, "C", "baseC"))
 		
 		extended = cache.FindNamedInterface("Extended.XYZ")
-		p = extended.GetParams()
+		p = extended.GetParams(cache)
 		self.failUnless(self.checkForParam(p, "A", None))
 		self.failUnless(self.checkForParam(p, "B", "baseB"))
 		self.failUnless(self.checkForParam(p, "C", "extC"))
 		self.failUnless(self.checkForParam(p, "D", None))
-		f = extended.GetFLMIncludePath()
+		f = extended.GetFLMIncludePath(cache=cache)
 		self.assertEqual(f.File(), "ext.flm")
 		
 		extended = cache.FindNamedInterface("Extended2.XYZ")
-		p = extended.GetParams()
+		p = extended.GetParams(cache)
 		self.failUnless(self.checkForParam(p, "A", None))
 		self.failUnless(self.checkForParam(p, "B", "baseB"))
 		self.failUnless(self.checkForParam(p, "C", "extC"))
 		self.failUnless(self.checkForParam(p, "D", None))
-		f = extended.GetFLMIncludePath()
+		f = extended.GetFLMIncludePath(cache)
 		self.assertEqual(f.File(), "base.flm")
 	
 	
--- a/sbsv2/raptor/test/unit_suite/raptor_make_unit.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/unit_suite/raptor_make_unit.py	Mon Nov 16 20:39:37 2009 +0000
@@ -71,14 +71,12 @@
 		svar.AddOperation(raptor_data.Set("EXEPARAM1", "parameter 1"))
 		svar.AddOperation(raptor_data.Set("EXEPARAM2", "parameter 2"))
 		spec.AddVariant(svar)
-		spec.SetOwner(aRaptor)
 		
 		# use a minimal Configuration
 		conf = raptor_data.Variant("myConfig")
 		cvar = raptor_data.Variant("CVAR")
 		cvar.AddOperation(raptor_data.Set("EXEPARAM3", "parameter 3"))
 		bldunit = raptor_data.BuildUnit("myConfig.CVAR",[conf,cvar])
-		conf.SetOwner(aRaptor)
 		
 		# delete any old Makefiles
 		m1 = testDir.Append("Makefile")
@@ -148,7 +146,6 @@
 		#
 		top1.AddChildSpecification(top1c1)
 		top1.AddChildSpecification(top1c2)
-		top1.SetOwner(aRaptor)
 		
 		# top 2 has no sub-nodes
 		top2 = raptor_data.Specification("top2")
@@ -157,7 +154,6 @@
 		top2v.AddOperation(raptor_data.Set("EXEPARAM1", "top2 p1"))
 		top2.AddVariant(top2v)
 		#
-		top2.SetOwner(aRaptor)
 		
 		# use a pair of minimal Configurations
 		
@@ -165,13 +161,11 @@
 		c1var = raptor_data.Variant()
 		c1var.AddOperation(raptor_data.Set("EXEPARAM2", "conf1 p2"))
 		buildunit1 = raptor_data.BuildUnit("conf1.c1var",[conf1,c1var])
-		conf1.SetOwner(aRaptor)
 		
 		conf2 = raptor_data.Variant("conf2")
 		c2var = raptor_data.Variant()
 		c2var.AddOperation(raptor_data.Set("EXEPARAM2", "conf2 p2"))
 		buildunit2 = raptor_data.BuildUnit("conf2.c2var",[conf2,c2var])
-		conf2.SetOwner(aRaptor)
 		
 		# delete any old Makefiles
 		makefiles = [testDir.Append("Makefile")]
@@ -205,6 +199,7 @@
 		aRaptor.LoadCache()
 		aRaptor.pruneDuplicateMakefiles = False
 		aRaptor.writeSingleMakefile = False
+		aRaptor.debugOutput = True
 		
 		# find the test directory
 		testDir = aRaptor.home.Append("test", "tmp")
@@ -258,7 +253,6 @@
 		#
 		top.Else.AddChildSpecification(childF)
 		
-		top.SetOwner(aRaptor)
 		
 		# Configurations
 		
@@ -267,42 +261,36 @@
 		confAv.AddOperation(raptor_data.Set("SWITCH", "confA switch"))
 		confAv.AddOperation(raptor_data.Set("TOGGLE", "confA toggle"))
 		b1 = raptor_data.BuildUnit("confA.confAv",[confA,confAv])
-		confA.SetOwner(aRaptor)
 		
 		confB = raptor_data.Variant("confB")	# hit
 		confBv = raptor_data.Variant()
 		confBv.AddOperation(raptor_data.Set("SWITCH", "confB switch"))
 		confBv.AddOperation(raptor_data.Set("TOGGLE", "confB toggle"))
 		b2 = raptor_data.BuildUnit("confB.confBv",[confB,confBv])
-		confB.SetOwner(aRaptor)
 		
 		confC = raptor_data.Variant("confC")
 		confCv = raptor_data.Variant()
 		confCv.AddOperation(raptor_data.Set("SWITCH", "confC switch"))
 		confCv.AddOperation(raptor_data.Set("TOGGLE", "confC toggle"))
 		b3 = raptor_data.BuildUnit("confC.confCv",[confC,confCv])
-		confC.SetOwner(aRaptor)
 		
 		confD = raptor_data.Variant("confD")
 		confDv = raptor_data.Variant()
 		confDv.AddOperation(raptor_data.Set("SWITCH", "ARM"))	# hit
 		confDv.AddOperation(raptor_data.Set("TOGGLE", "confD toggle"))
 		b4 = raptor_data.BuildUnit("confD.confDv",[confD,confDv])
-		confD.SetOwner(aRaptor)
 		
 		confE = raptor_data.Variant("confE")
 		confEv = raptor_data.Variant()
 		confEv.AddOperation(raptor_data.Set("SWITCH", "confE switch"))
 		confEv.AddOperation(raptor_data.Set("TOGGLE", "B"))		# hit
 		b5 = raptor_data.BuildUnit("confE.confEv",[confE,confEv])
-		confE.SetOwner(aRaptor)
 		
 		confF = raptor_data.Variant("confF")
 		confFv = raptor_data.Variant()
 		confFv.AddOperation(raptor_data.Set("SWITCH", "confF switch"))
 		confFv.AddOperation(raptor_data.Set("TOGGLE", "confF toggle"))
 		b6 = raptor_data.BuildUnit("confF.confFv",[confF,confFv])
-		confF.SetOwner(aRaptor)
 		
 		# delete any old Makefiles
 		makefiles = [testDir.Append("Makefile")]
@@ -322,7 +310,7 @@
 		
 		# create new Makefiles
 		maker = raptor_make.MakeEngine(aRaptor)
-		maker.Write(makefiles[0], [top], [b1,b2,b3,b4,b5,b6])
+		maker.Write(makefiles[0], specs=[top], configs=[b1,b2,b3,b4,b5,b6])
 		
 		# test and clean
 		self.failUnless(self.checkMakefiles(makefiles))
@@ -353,25 +341,19 @@
 		
 		f1 = raptor_data.Filter("f1")
 		f1.SetConfigCondition("c1")
-		f1.SetOwner(aRaptor)
 		
 		f2 = raptor_data.Filter("f2")
 		f2.SetConfigCondition("c2")
 		f2.SetInterface(iface)
-		f2.SetOwner(aRaptor)
 		
 		f3 = raptor_data.Filter("f3")
 		f3.SetConfigCondition("c3")
 		f3.SetInterface(iface)
-		f3.SetOwner(aRaptor)
 		
 		# Configurations
 		c1 = raptor_data.Variant("c1")
-		c1.SetOwner(aRaptor)
 		c2 = raptor_data.Variant("c2")
-		c2.SetOwner(aRaptor)
 		c3 = raptor_data.Variant("c3")
-		c3.SetOwner(aRaptor)
 
 		# Build Units
 		b1 = raptor_data.BuildUnit("c1",[c1])
--- a/sbsv2/raptor/test/unit_suite/raptor_meta_unit.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/unit_suite/raptor_meta_unit.py	Mon Nov 16 20:39:37 2009 +0000
@@ -147,7 +147,7 @@
 			self.__gnucpp = "cpp" 
 		if os.environ.has_key('GNUCPP'):
 			self.__gnucpp = os.environ['GNUCPP']
-		
+	
 	def testPreProcessor(self):
 		# Just test for correct behaviour on failure, other tests excercise correct behaviour on success
 		preProcessor = raptor_meta.PreProcessor('cpp_that_does_not_exist', 
@@ -202,7 +202,8 @@
 		bldInfFile = aRootBldInfLocation.Append(aBldInfFile)
 		self.failUnless(bldInfFile)
 		
-		bldInfObject = raptor_meta.BldInfFile(bldInfFile, self.__gnucpp, self.raptor)
+		depfiles=[]
+		bldInfObject = raptor_meta.BldInfFile(bldInfFile, self.__gnucpp, depfiles=depfiles, log=self.raptor)
 		
 		bp = bldInfObject.getBuildPlatforms(self.defaultPlatform)
 		self.assertEquals(bp, aExpectedBldInfPlatforms)
@@ -246,7 +247,8 @@
 		bldInfTestRoot = self.__testRoot.Append('metadata/project/mmps/test_mmps')
 		
 		bldInfFile = bldInfTestRoot.Append('test_mmps.inf')
-		bldInfObject = raptor_meta.BldInfFile(bldInfFile, self.__gnucpp, self.raptor)
+		depfiles = []
+		bldInfObject = raptor_meta.BldInfFile(bldInfFile, self.__gnucpp, depfiles=depfiles, log=self.raptor)
 		testArmv5Platform = self.ARMV5
 		testArmv5Platform["TESTCODE"] = True
 		bldInfObject.getRomTestType(testArmv5Platform)
@@ -273,8 +275,9 @@
 		bldInfTestRoot = self.__testRoot.Append('metadata/project/bld.infs')
 		bldInfMakefilePathTestRoot = str(self.__makefilePathTestRoot) + '/metadata/project/'
 		
+		depfiles = []
 		bldInfObject = raptor_meta.BldInfFile(bldInfTestRoot.Append('exports.inf'), 
-											  self.__gnucpp, self.raptor)
+											  self.__gnucpp, depfiles=depfiles, log=self.raptor)
 					
 		exports = bldInfObject.getExports(self.defaultPlatform)
 		
@@ -491,8 +494,9 @@
 	def testBldInfExtensions(self):
 		bldInfTestRoot = self.__testRoot.Append('metadata/project/bld.infs')
 		bldInfMakefilePathTestRoot = str(self.__makefilePathTestRoot)+'/metadata/project/bld.infs'			
+		depfiles = []
 		bldInfObject = raptor_meta.BldInfFile(bldInfTestRoot.Append('extensions.inf'),
-											  self.__gnucpp, self.raptor)
+											  self.__gnucpp, depfiles=depfiles, log=self.raptor)
 		
 		extensions = bldInfObject.getExtensions(self.ARMV5)
 		
@@ -565,8 +569,9 @@
 		
 	def testBldInfIncludes(self):
 		bldInfTestRoot = self.__testRoot.Append('metadata/project/bld.infs/includes')
+		depfiles=[]
 		bldInfObject = raptor_meta.BldInfFile(bldInfTestRoot.Append('top_level.inf'),
-											  self.__gnucpp, self.raptor)
+											  self.__gnucpp, depfiles=depfiles, log=self.raptor)
 		Root = str(bldInfTestRoot)
 		
 		mmpFiles = bldInfObject.getMMPList(self.ARMV5)
@@ -582,15 +587,19 @@
 
 	def testMmpIncludes(self):
 		mmpTestRoot = self.__testRoot.Append('metadata/project/mmps/includes')
-		mmpMakefilePathTestRoot = str(self.__makefilePathTestRoot)+'/metadata/project/mmps/includes'			
+		mmpMakefilePathTestRoot = str(self.__makefilePathTestRoot)+'/metadata/project/mmps/includes'
+
+		depfiles=[]
 		bldInfObject = raptor_meta.BldInfFile(mmpTestRoot.Append('top_level.inf'),
-											  self.__gnucpp, self.raptor)
+										 self.__gnucpp, depfiles=depfiles, log=self.raptor)
 		
 		mmpFiles = bldInfObject.getMMPList(self.ARMV5)
+		mmpdeps = []
 		mmpFile = raptor_meta.MMPFile(mmpFiles['mmpFileList'][0].filename, 
 										   self.__gnucpp,
 										   bldInfObject,
-										   self.raptor)
+									           depfiles=mmpdeps,
+										   log=self.raptor)
 		
 		self.assertEquals(str(mmpFile.filename), 
 						  str(mmpTestRoot.Append("top_level.mmp")))
@@ -728,20 +737,32 @@
 		
 		for t in defFileTests:
 			self.assertEquals(t.test(self.raptor), True)
-		
+	
+	def dummyMetaReader(self):
+		"make raptor_meta.MetaReader.__init__ into a none operation"
+		self.savedInit = raptor_meta.MetaReader.__init__
+
+		def DummyMetaReaderInit(self, aRaptor):
+			self._MetaReader__Raptor = aRaptor
+
+		raptor_meta.MetaReader.__init__ = DummyMetaReaderInit
+
+	def restoreMetaReader(self):
+		"make raptor_meta.MetaReader.__init__ operational again"
+		raptor_meta.MetaReader.__init__ = self.savedInit
+
 	def testApplyOsVariant(self):
+		self.dummyMetaReader()
+
 		# Mock output class
 		class OutputMock(object):
 			def write(self, text):
 				pass
 				
-		def MetaReaderInitFunction(self, aRaptor):
-			self._MetaReader__Raptor = aRaptor
-		
 		bu = raptor_data.BuildUnit("os_variant", [])
 					
 		self.raptor.keepGoing = False
-		raptor_meta.MetaReader.__init__ = MetaReaderInitFunction
+		
 		metaReader = raptor_meta.MetaReader(self.raptor)
 		metaReader.ApplyOSVariant(bu, ".")
 
@@ -750,6 +771,8 @@
 		metaReader = raptor_meta.MetaReader(self.raptor)	
 		metaReader.ApplyOSVariant(bu, ".")
 
+		self.restoreMetaReader()
+
 	def __assertEqualStringList(self, aListOne, aListTwo):
 		self.assertEquals(len(aListOne), len(aListTwo))
 		
@@ -799,6 +822,8 @@
 		self.__assertEqualStringList(results, ['--assignmentArgU=value1<->--assignmentArgV=value2'])
 	
 	def testModuleName(self):
+		self.dummyMetaReader()
+
 		# Test how we resolve known permutations of values given to the .mmp file OPTION_REPLACE keyword
 		mockBackend = raptor_meta.MetaReader(self.raptor)
 		
@@ -816,6 +841,8 @@
 		for result in resultsDictList:
 			moduleName = mockBackend.ModuleName(result["bldinf"])
 			self.assertEquals(moduleName, result["result"])
+
+		self.restoreMetaReader()
 		
 # run all the tests
 
--- a/sbsv2/raptor/test/unit_suite/raptor_unit.py	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/test/unit_suite/raptor_unit.py	Mon Nov 16 20:39:37 2009 +0000
@@ -17,6 +17,8 @@
 
 import raptor
 import raptor_version
+import raptor_meta
+import raptor_utilities
 import re
 import unittest
 import generic_path
@@ -38,7 +40,7 @@
 		
 
 	def testVersion(self):
-		self.failUnless(re.match("^\d+\.\d+\.", raptor_version.Version()))
+		self.failUnless(re.match("^\d+\.\d+\.", raptor_version.fullversion()))
 
 
 	def testCLISupport(self):
@@ -56,10 +58,66 @@
 		r.SetSysDefBase("C:\\mysysdef")
 		r.AddBuildInfoFile("build.info")
 		r.SetTopMakefile("E:\\epoc32\\build\\Makefile")
+		
+		
+	def testComponentListParsing(self):
+		expected_spec_output = [
+				'test/smoke_suite/test_resources/simple/bld.inf',
+				'test/smoke_suite/test_resources/simple_export/bld.inf',
+				'test/smoke_suite/test_resources/simple_dll/bld.inf',
+				'test/smoke_suite/test_resources/simple_extension/bld.inf',
+				'test/smoke_suite/test_resources/simple_gui/Bld.inf',
+				'TOOLS2 SHOULD NOT APPEAR IN THE OUTPUT']
+		
+		r = raptor.Raptor()
+		null_log_instance = raptor_utilities.NullLog()
+		r.Info = null_log_instance.Info 
+		r.Debug = null_log_instance.Debug
+		r.Warn = null_log_instance.Warn
+		r.ConfigFile()
+		r.ProcessConfig()
+		# Note that tools2/bld.inf specifies tools2 as the only supported
+		# platform, so it should not appear in the component list at the end
+		r.CommandLine([
+				'-b', 'smoke_suite/test_resources/simple/bld.inf',
+				'-b', 'smoke_suite/test_resources/simple_dll/bld.inf',
+				'-b', 'smoke_suite/test_resources/simple_export/bld.inf',
+				'-b', 'smoke_suite/test_resources/simple_extension/bld.inf',
+				'-b', 'smoke_suite/test_resources/simple_gui/Bld.inf',
+				'-b', 'smoke_suite/test_resources/tools2/bld.inf',
+				'-c', 'armv5'])
+		# establish an object cache
+		r.LoadCache()
+		buildUnitsToBuild = r.GetBuildUnitsToBuild(r.configNames)
+		# find out what components to build, and in what way
+		layers = []
+		layers = r.GetLayersFromCLI()
+		
+		generic_specs = r.GenerateGenericSpecs(buildUnitsToBuild)
+		
+		specs = []
+		specs.extend(generic_specs)
+		metaReader = raptor_meta.MetaReader(r, buildUnitsToBuild)
+		specs.extend(metaReader.ReadBldInfFiles(layers[0].children,
+				False))
+
+		# See what components are actually built for the given configs
+		# should be only 5 since 1 is a tools component and we're building armv5
+		hits = 0
+		for c in layers[0].children:
+			if len(c.specs) > 0: 
+				# something will be built from this component because
+				# it has at least one spec
+				shortname = str(c.bldinf_filename)[len(os.environ['SBS_HOME'])+1:]
+				self.assertTrue(shortname in expected_spec_output)
+				hits += 1
+
+		# Ensure there actually are 5 build specs
+		self.assertEqual(hits, len(expected_spec_output) - 1)
+
 
 	def setUp(self):
 		self.r = raptor.Raptor()
-		self.r.out = OutputMock()
 		
 		self.cwd = generic_path.CurrentDir()
 		self.isFileReturningFalse = lambda: False
@@ -68,42 +126,44 @@
 		self.sysDef = self.cwd.Append(self.r.systemDefinition)
 		self.bldInf = self.cwd.Append(self.r.buildInformation)
 
-	def testCreateWarningForNonexistingBldInfAndSystemDefinitionFile(self): 
+	def testWarningIfSystemDefinitionFileDoesNotExist(self): 
 		"""Test if sbs creates warning if executed without specified 
 		component to build i.e. default bld.inf (bld.inf in current 
 		directory) or system definition file.
 
 		Uses an empty temporary directory for this."""
+		self.r.out = OutputMock()
 
 		d = tempfile.mkdtemp(prefix='raptor_test') 
 		cdir = os.getcwd()
 		os.chdir(d) 
-		self.r.GetComponentGroupsFromCLI()
+		layers = self.r.GetLayersFromCLI()
 		os.chdir(cdir) # go back
 		os.rmdir(d)
 		
 		self.assertTrue(self.r.out.warningWritten())
 
-	def testCreateWarningForExistingBldInf(self):
 		d = tempfile.mkdtemp(prefix='raptor_test') 
 		cdir = os.getcwd()
 		os.chdir(d)
 		f = open("bld.inf","w")
 		f.close()
-		self.r.GetComponentGroupsFromCLI()
+		layers = self.r.GetLayersFromCLI()
 		os.unlink("bld.inf")
 		os.chdir(cdir) # go back
 		os.rmdir(d)
 
-		self.assertFalse(self.r.out.warningWritten())
+		self.assertTrue(self.r.out.warningWritten())
 
-	def testCreateWarningForExistingSystemDefinitionFile(self): 
+	def testNoWarningIfSystemDefinitionFileExists(self): 
+		self.r.out = OutputMock()
+
 		d = tempfile.mkdtemp(prefix='raptor_test') 
 		cdir = os.getcwd()
 		os.chdir(d)
 		f = open("System_Definition.xml","w")
 		f.close()
-		self.r.GetComponentGroupsFromCLI()
+		layers = self.r.GetLayersFromCLI()
 		os.unlink("System_Definition.xml")
 		os.chdir(cdir) # go back
 		os.rmdir(d)
@@ -112,32 +172,38 @@
 	
 	# Test Info, Warn & Error functions can handle attributes
 	def testInfoAttributes(self):
+		self.r.out = OutputMock()
 		self.r.Info("hello %s", "world", planet="earth")
 		expected = "<info planet='earth'>hello world</info>\n"
 		self.assertEquals(self.r.out.actual, expected)
 		
 	def testWarnAttributes(self):
+		self.r.out = OutputMock()
 		self.r.Warn("look out", where="behind you")
 		expected = "<warning where='behind you'>look out</warning>\n"
 		self.assertEquals(self.r.out.actual, expected)
 		
 	def testErrorAttributes(self):
+		self.r.out = OutputMock()
 		self.r.Error("messed up %s and %s", "all", "sundry", bldinf="bld.inf")
 		expected = "<error bldinf='bld.inf'>messed up all and sundry</error>\n"
 		self.assertEquals(self.r.out.actual, expected)	
 		
 	# Test Info, Warn & Error functions to ensure XML control chars are escaped
 	def testInfoXMLEscaped(self):
+		self.r.out = OutputMock()
 		self.r.Info("h&l>o<&amp;")
 		expected = "<info>h&amp;l&gt;o&lt;&amp;amp;</info>\n"
 		self.assertEquals(self.r.out.actual, expected)
 		
 	def testWarnXMLEscaped(self):
+		self.r.out = OutputMock()
 		self.r.Warn("h&l>o<&amp;")
 		expected = "<warning>h&amp;l&gt;o&lt;&amp;amp;</warning>\n"
 		self.assertEquals(self.r.out.actual, expected)
 		
 	def testErrorXMLEscaped(self):
+		self.r.out = OutputMock()
 		self.r.Error("h&l>o<&amp;")
 		expected = "<error>h&amp;l&gt;o&lt;&amp;amp;</error>\n"
 		self.assertEquals(self.r.out.actual, expected)
@@ -146,14 +212,16 @@
 # Mock output class preserving output for checking
 # Can also check if any warning has been written
 class OutputMock(object):
-	actual = ""
+	warningRegExp = re.compile(".*warning.*")
+
+	def __init__(self):
+		self.actual = ""
 	
 	def write(self, text):
-		self.actual = text
+		self.actual += text
 		
 	def warningWritten(self):
-		regExp = re.compile(".*warning.*")
-		if regExp.match(self.actual):
+		if OutputMock.warningRegExp.match(self.actual):
 			return True
 		return False
 			
--- a/sbsv2/raptor/util/install-windows/raptorinstallerscript.nsi	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/util/install-windows/raptorinstallerscript.nsi	Mon Nov 16 20:39:37 2009 +0000
@@ -103,17 +103,17 @@
 	
     # Install Raptor
     SetOutPath "$INSTDIR\bin"
-    File /r ${RAPTOR_LOCATION}\bin\*.* 
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\bin\*.* 
     SetOutPath "$INSTDIR\examples"
-    File /r ${RAPTOR_LOCATION}\examples\*.*
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\examples\*.*
     SetOutPath "$INSTDIR\lib"
-    File /r ${RAPTOR_LOCATION}\lib\*.*
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\lib\*.*
     SetOutPath "$INSTDIR\python"
-    File /r ${RAPTOR_LOCATION}\python\*.*
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\python\*.*
     SetOutPath "$INSTDIR\schema"
-    File /r ${RAPTOR_LOCATION}\schema\*.*
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\schema\*.*
     SetOutPath "$INSTDIR\win32"
-    File /r ${RAPTOR_LOCATION}\win32\*.*
+    File /r /x distribution.policy.s60 ${RAPTOR_LOCATION}\win32\*.*
     
     SetOutPath "$INSTDIR"
     File ${RAPTOR_LOCATION}\RELEASE-NOTES.txt
--- a/sbsv2/raptor/util/talon/lock.c	Mon Nov 16 09:46:46 2009 +0000
+++ b/sbsv2/raptor/util/talon/lock.c	Mon Nov 16 20:39:37 2009 +0000
@@ -12,7 +12,7 @@
 * Contributors:
 *
 * Description: 
-*
+* Test program for grabbing and releasing the talon output semaphore.
 */