sbsv2/raptor/python/raptor_meta.py
branchwip
changeset 5 593a8820b912
parent 3 e1eecf4d390d
child 9 b211d87c390a
child 11 ea23b18a2ff6
--- 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