sbsv2/raptor/python/raptor_meta.py
branchfix
changeset 39 164b0547f8a5
parent 32 fdfc59a2ae7e
child 44 cf0c187b284a
child 48 f872a2538607
equal deleted inserted replaced
6:29df63210f13 39:164b0547f8a5
   230 		commentDetail.append(linenumber)
   230 		commentDetail.append(linenumber)
   231 
   231 
   232 	return commentDetail
   232 	return commentDetail
   233 
   233 
   234 
   234 
       
   235 def getSpecName(aFileRoot, fullPath=False):
       
   236 	"""Returns a build spec name: this is the file root (full path
       
   237 	or simple file name) made safe for use as a file name."""
       
   238 
       
   239 	if fullPath:
       
   240 		specName = str(aFileRoot).replace("/","_")
       
   241 		specName = specName.replace(":","")
       
   242 	else:
       
   243 		specName = aFileRoot.File()
       
   244 
       
   245 	return specName.lower()
       
   246 
       
   247 
   235 # Classes
   248 # Classes
   236 
   249 
   237 class MetaDataError(Exception):
   250 class MetaDataError(Exception):
   238 	"""Fatal error wrapper, to be thrown directly back to whatever is calling."""
   251 	"""Fatal error wrapper, to be thrown directly back to whatever is calling."""
   239 
   252 
   282 		self.raptor = aRaptor
   295 		self.raptor = aRaptor
   283 
   296 
   284 	def call(self, aArgs, sourcefilename):
   297 	def call(self, aArgs, sourcefilename):
   285 		""" Override call so that we can do our own error handling."""
   298 		""" Override call so that we can do our own error handling."""
   286 		tool = self._ExternalTool__Tool
   299 		tool = self._ExternalTool__Tool
       
   300 		commandline = tool + " " + aArgs + " " + str(sourcefilename)
   287 		try:
   301 		try:
   288 			commandline = tool + " " + aArgs + " " + str(sourcefilename)
       
   289 
       
   290 			# the actual call differs between Windows and Unix
   302 			# the actual call differs between Windows and Unix
   291 			if raptor_utilities.getOSFileSystem() == "unix":
   303 			if raptor_utilities.getOSFileSystem() == "unix":
   292 				p = subprocess.Popen(commandline, \
   304 				p = subprocess.Popen(commandline, \
   293 									 shell=True, bufsize=65535, \
   305 									 shell=True, bufsize=65535, \
   294 									 stdin=subprocess.PIPE, \
   306 									 stdin=subprocess.PIPE, \
   330 							actualErr = True
   342 							actualErr = True
   331 			if actualErr:
   343 			if actualErr:
   332 				raise MetaDataError("Errors in %s" % str(sourcefilename))
   344 				raise MetaDataError("Errors in %s" % str(sourcefilename))
   333 
   345 
   334 		except Exception,e:
   346 		except Exception,e:
   335 			raise MetaDataError("Preprocessor exception: %s" % str(e))
   347 			raise MetaDataError("Preprocessor exception: '%s' : in command : '%s'" % (str(e), commandline))
   336 
   348 
   337 		return 0	# all OK
   349 		return 0	# all OK
   338 
   350 
   339 	def setMacros(self, aMacros):
   351 	def setMacros(self, aMacros):
   340 		self.__Macros = aMacros
   352 		self.__Macros = aMacros
   396 
   408 
   397 	Symbian metadata files are subject to preprocessing, primarily with macros based
   409 	Symbian metadata files are subject to preprocessing, primarily with macros based
   398 	on the selected build platform.  This class provides a generic means of wrapping
   410 	on the selected build platform.  This class provides a generic means of wrapping
   399 	up the preprocessing of such files."""
   411 	up the preprocessing of such files."""
   400 
   412 
   401 	def __init__(self, aFilename, gnucpp, aRootLocation=None, log=None):
   413 	def __init__(self, aFilename, gnucpp, depfiles, aRootLocation=None, log=None):
   402 		"""
   414 		"""
   403 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
   415 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
   404 		@param aDefaultPlatform  Default preprocessed version of this file
   416 		@param aDefaultPlatform  Default preprocessed version of this file
   405 		@param aCPP 		location of GNU CPP
   417 		@param aCPP 		location of GNU CPP
       
   418 		@param depfiles     	list to add dependency file tuples to
       
   419 		@param aRootLocation    where the file is 
   406 		@param log 		A class with Debug(<string>), Info(<string>) and Error(<string>) methods
   420 		@param log 		A class with Debug(<string>), Info(<string>) and Error(<string>) methods
   407 		"""
   421 		"""
   408 		self.filename = aFilename
   422 		self.filename = aFilename
   409 		self.__RootLocation = aRootLocation
   423 		self.__RootLocation = aRootLocation
   410 		# Dictionary with key of build platform and a text string of processed output as values
   424 		# Dictionary with key of build platform and a text string of processed output as values
   411 		self.__PreProcessedContent = {}
   425 		self.__PreProcessedContent = {}
   412 		self.log = log
   426 		self.log = log
       
   427 		self.depfiles = depfiles
   413 
   428 
   414 		self.__gnucpp = gnucpp
   429 		self.__gnucpp = gnucpp
   415 		if gnucpp is None:
   430 		if gnucpp is None:
   416 			raise ValueError('gnucpp must be set')
   431 			raise ValueError('gnucpp must be set')
   417 
   432 
   434 			if raptor_utilities.getOSPlatform().startswith("win"):
   449 			if raptor_utilities.getOSPlatform().startswith("win"):
   435 				metatarget = "$(PARSETARGET)"
   450 				metatarget = "$(PARSETARGET)"
   436 			else:
   451 			else:
   437 				metatarget = "'$(PARSETARGET)'"
   452 				metatarget = "'$(PARSETARGET)'"
   438 			generateDepsOptions = "-MD -MF%s -MT%s" % (adepfilename, metatarget)
   453 			generateDepsOptions = "-MD -MF%s -MT%s" % (adepfilename, metatarget)
   439 			aBuildPlatform['METADEPS'].append((adepfilename, metatarget))
   454 			self.depfiles.append((adepfilename, metatarget))
   440 			try:
   455 			try:
   441 				os.makedirs(os.path.dirname(adepfilename))
   456 				os.makedirs(os.path.dirname(adepfilename))
   442 			except Exception, e:
   457 			except Exception, e:
   443 				self.log.Debug("Couldn't make bldinf outputpath for dependency generation")
   458 				self.log.Debug("Couldn't make bldinf outputpath for dependency generation")
   444 
   459 
   513 
   528 
   514 	Symbian metadata files are subject to preprocessing, primarily with macros based
   529 	Symbian metadata files are subject to preprocessing, primarily with macros based
   515 	on the selected build platform.  This class provides a generic means of wrapping
   530 	on the selected build platform.  This class provides a generic means of wrapping
   516 	up the preprocessing of such files."""
   531 	up the preprocessing of such files."""
   517 
   532 
   518 	def __init__(self, aFilename, gnucpp, bldinf, log=None):
   533 	def __init__(self, aFilename, gnucpp, bldinf, depfiles, log=None):
   519 		"""
   534 		"""
   520 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
   535 		@param aFilename	An MMP, bld.inf or other preprocessable build spec file
   521 		@param gnucpp 		location of GNU CPP
   536 		@param gnucpp 		location of GNU CPP
   522 		@param bldinf   	the bldinf file that this mmp comes from
   537 		@param bldinf		the bld.inf file this mmp was specified in
   523 		@param log 			A class with Debug(<string>), Info(<string>) and Error(<string>) methods
   538 		@param depfiles         list to fill with mmp dependency files
       
   539 		@param log 		A class with Debug(<string>), Info(<string>) and Error(<string>) methods
   524 		"""
   540 		"""
   525 		super(MMPFile, self).__init__(aFilename, gnucpp, str(bldinf.filename.Dir()), log)
   541 		super(MMPFile, self).__init__(aFilename, gnucpp, depfiles, str(bldinf.filename.Dir()),  log)
   526 		self.__bldinf = bldinf
   542 		self.__bldinf = bldinf
       
   543 		self.depfiles = depfiles
   527 
   544 
   528 		self.__gnucpp = gnucpp
   545 		self.__gnucpp = gnucpp
   529 		if gnucpp is None:
   546 		if gnucpp is None:
   530 			raise ValueError('gnucpp must be set')
   547 			raise ValueError('gnucpp must be set')
   531 
   548 
   876 
   893 
   877 
   894 
   878 class BldInfFile(MetaDataFile):
   895 class BldInfFile(MetaDataFile):
   879 	"""Representation of a Symbian bld.inf file"""
   896 	"""Representation of a Symbian bld.inf file"""
   880 
   897 
   881 	def __init__(self, aFilename, gnucpp, log=None):
   898 	def __init__(self, aFilename, gnucpp, depfiles, log=None):
   882 		MetaDataFile.__init__(self, aFilename, gnucpp, None, log)
   899 		MetaDataFile.__init__(self, aFilename, gnucpp, depfiles, None, log)
   883 		self.__Raptor = log
   900 		self.__Raptor = log
   884 		self.testManual = 0
   901 		self.testManual = 0
   885 		self.testAuto = 0
   902 		self.testAuto = 0
   886 	# Generic
   903 	# Generic
   887 
   904 
  1192 
  1209 
  1193 	def __init__(self, aRaptor, aMmpfilename, aBldInfFilename):
  1210 	def __init__(self, aRaptor, aMmpfilename, aBldInfFilename):
  1194 		super(MMPRaptorBackend,self).__init__()
  1211 		super(MMPRaptorBackend,self).__init__()
  1195 		self.platformblock = None
  1212 		self.platformblock = None
  1196 		self.__Raptor = aRaptor
  1213 		self.__Raptor = aRaptor
  1197 		self.BuildVariant = raptor_data.Variant()
  1214 		self.__debug("-----+++++ %s " % aMmpfilename)
       
  1215 		self.BuildVariant = raptor_data.Variant(name = "mmp")
       
  1216 		self.ApplyVariants = []
  1198 		self.ResourceVariants = []
  1217 		self.ResourceVariants = []
  1199 		self.BitmapVariants = []
  1218 		self.BitmapVariants = []
  1200 		self.StringTableVariants = []
  1219 		self.StringTableVariants = []
  1201 		self.__bldInfFilename = aBldInfFilename
  1220 		self.__bldInfFilename = aBldInfFilename
  1202 		self.__targettype = "UNKNOWN"
  1221 		self.__targettype = "UNKNOWN"
  1206 		self.__sourcepath = raptor_utilities.resolveSymbianPath(self.__currentMmpFile, "")
  1225 		self.__sourcepath = raptor_utilities.resolveSymbianPath(self.__currentMmpFile, "")
  1207 		self.__userinclude = ""
  1226 		self.__userinclude = ""
  1208 		self.__systeminclude = ""
  1227 		self.__systeminclude = ""
  1209 		self.__bitmapSourcepath = self.__sourcepath
  1228 		self.__bitmapSourcepath = self.__sourcepath
  1210 		self.__current_resource = ""
  1229 		self.__current_resource = ""
  1211 		self.__capabilities = []
       
  1212 		self.__resourceFiles = []
  1230 		self.__resourceFiles = []
  1213 		self.__pageConflict = []
  1231 		self.__pageConflict = []
  1214 		self.__debuggable = ""
  1232 		self.__debuggable = ""
       
  1233 		self.__compressionKeyword = ""
  1215 		self.sources = []
  1234 		self.sources = []
       
  1235 		self.capabilities = []
  1216 
  1236 
  1217 		self.__TARGET = ""
  1237 		self.__TARGET = ""
  1218 		self.__TARGETEXT = ""
  1238 		self.__TARGETEXT = ""
  1219 		self.deffile = ""
  1239 		self.deffile = ""
  1220 		self.__LINKAS = ""
  1240 		self.__LINKAS = ""
  1336 				self.__Raptor.Warn("DEBUGGABLE keyword has no effect as DEBUGGABLE or DEBUGGABLE_UDEBONLY is already set")
  1356 				self.__Raptor.Warn("DEBUGGABLE keyword has no effect as DEBUGGABLE or DEBUGGABLE_UDEBONLY is already set")
  1337 			self.__debuggable = "udeb"
  1357 			self.__debuggable = "udeb"
  1338 		elif varname == 'FEATUREVARIANT':
  1358 		elif varname == 'FEATUREVARIANT':
  1339 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"1"))
  1359 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"1"))
  1340 			self.featureVariant = True
  1360 			self.featureVariant = True
       
  1361 		elif varname in ['COMPRESSTARGET', 'NOCOMPRESSTARGET', 'INFLATECOMPRESSTARGET', 'BYTEPAIRCOMPRESSTARGET']:
       
  1362 			if self.__compressionKeyword:
       
  1363 				self.__Raptor.Warn("%s keyword in %s overrides earlier use of %s" % (varname, self.__currentMmpFile, self.__compressionKeyword))
       
  1364 				self.BuildVariant.AddOperation(raptor_data.Set(self.__compressionKeyword,""))
       
  1365 				self.__debug( "Set switch " + varname + " OFF")
       
  1366 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"1"))
       
  1367 			self.__debug( "Set switch " + varname + " ON")
       
  1368 			self.__compressionKeyword = varname
  1341 		else:
  1369 		else:
  1342 			self.__debug( "Set switch "+toks[0]+" ON")
  1370 			self.__debug( "Set switch "+toks[0]+" ON")
  1343 			self.BuildVariant.AddOperation(raptor_data.Set(prefix+varname, "1"))
  1371 			self.BuildVariant.AddOperation(raptor_data.Set(prefix+varname, "1"))
  1344 
  1372 
  1345 		return "OK"
  1373 		return "OK"
  1421 			self.__debug("Set "+varname+" to " + libName)
  1449 			self.__debug("Set "+varname+" to " + libName)
  1422 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(libName)))
  1450 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(libName)))
  1423 
  1451 
  1424 		elif varname=='CAPABILITY':
  1452 		elif varname=='CAPABILITY':
  1425 			for cap in toks[1]:
  1453 			for cap in toks[1]:
  1426 				self.BuildVariant.AddOperation(raptor_data.Append(varname,cap," "))
       
  1427 				self.__debug("Setting  "+toks[0]+": " + cap)
  1454 				self.__debug("Setting  "+toks[0]+": " + cap)
  1428 				self.__capabilities.append(cap.lower())
  1455 				self.capabilities.append(cap)
  1429 		elif varname=='DEFFILE':
  1456 		elif varname=='DEFFILE':
  1430 			self.__defFileRoot = self.__currentMmpFile
  1457 			self.__defFileRoot = self.__currentMmpFile
  1431 			self.deffile = toks[1]
  1458 			self.deffile = toks[1]
  1432 		elif varname=='LINKAS':
  1459 		elif varname=='LINKAS':
  1433 			self.__debug("Set "+toks[0]+"  OPTION to " + str(toks[1]))
  1460 			self.__debug("Set "+toks[0]+"  OPTION to " + str(toks[1]))
  1517 				toks1 = str(toks[1]).replace("\\","/")
  1544 				toks1 = str(toks[1]).replace("\\","/")
  1518 				if toks1.find(","):
  1545 				if toks1.find(","):
  1519 					toks1 = re.sub("[,'\[\]]", "", toks1).replace("//","/")
  1546 					toks1 = re.sub("[,'\[\]]", "", toks1).replace("//","/")
  1520 				self.__debug("Set "+toks[0]+" to " + toks1)
  1547 				self.__debug("Set "+toks[0]+" to " + toks1)
  1521 				self.BuildVariant.AddOperation(raptor_data.Set(varname,toks1))
  1548 				self.BuildVariant.AddOperation(raptor_data.Set(varname,toks1))
  1522 
  1549 		elif varname=='APPLY':
       
  1550 			self.ApplyVariants.append(toks[1])
  1523 		else:
  1551 		else:
  1524 			self.__debug("Set "+toks[0]+" to " + str(toks[1]))
  1552 			self.__debug("Set "+toks[0]+" to " + str(toks[1]))
  1525 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(toks[1])))
  1553 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(toks[1])))
  1526 
  1554 
  1527 			if varname=='LINKAS':
  1555 			if varname=='LINKAS':
  1765 					# be a replacement to consider
  1793 					# be a replacement to consider
  1766 					search = match
  1794 					search = match
  1767 					replace = ""
  1795 					replace = ""
  1768 					if len(matches):
  1796 					if len(matches):
  1769 						replace = matches.pop()
  1797 						replace = matches.pop()
  1770 					
  1798 
  1771 					searchReplacePairs.append('%s<->%s' % (search, replace))
  1799 					searchReplacePairs.append('%s<->%s' % (search, replace))
  1772 
  1800 
  1773 			# Replace spaces to maintain word-based grouping in downstream makefile lists
  1801 			# Replace spaces to maintain word-based grouping in downstream makefile lists
  1774 			for i in range(0,len(searchReplacePairs)):
  1802 			for i in range(0,len(searchReplacePairs)):
  1775 				searchReplacePairs[i] = searchReplacePairs[i].replace(' ','%20')
  1803 				searchReplacePairs[i] = searchReplacePairs[i].replace(' ','%20')
  1884 
  1912 
  1885 	def doStartBitmap(self,s,loc,toks):
  1913 	def doStartBitmap(self,s,loc,toks):
  1886 		self.__currentLineNumber += 1
  1914 		self.__currentLineNumber += 1
  1887 		self.__debug("Start BITMAP "+toks[1])
  1915 		self.__debug("Start BITMAP "+toks[1])
  1888 
  1916 
  1889 		self.__currentBitmapVariant = raptor_data.Variant(toks[1].replace('.','_'))
  1917 		self.__currentBitmapVariant = raptor_data.Variant(name = toks[1].replace('.','_'))
  1890 		# Use BMTARGET and BMTARGET_lower because that prevents
  1918 		# Use BMTARGET and BMTARGET_lower because that prevents
  1891 		# confusion with the TARGET and TARGET_lower of our parent MMP
  1919 		# confusion with the TARGET and TARGET_lower of our parent MMP
  1892 		# when setting the OUTPUTPATH.  This in turn allows us to
  1920 		# when setting the OUTPUTPATH.  This in turn allows us to
  1893 		# not get tripped up by multiple mbms being generated with
  1921 		# not get tripped up by multiple mbms being generated with
  1894 		# the same name to the same directory.
  1922 		# the same name to the same directory.
  1974 
  2002 
  1975 		self.__debug("sourcepath: " + self.__sourcepath)
  2003 		self.__debug("sourcepath: " + self.__sourcepath)
  1976 		self.__debug("stringtable: " + toks[1])
  2004 		self.__debug("stringtable: " + toks[1])
  1977 		self.__debug("adjusted stringtable source=" + source)
  2005 		self.__debug("adjusted stringtable source=" + source)
  1978 
  2006 
  1979 		self.__currentStringTableVariant = raptor_data.Variant(uniqname)
  2007 		self.__currentStringTableVariant = raptor_data.Variant(name = uniqname)
  1980 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source))
  2008 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source))
  1981 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", ""))
  2009 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", ""))
  1982 		self.__stringtableExported = False
  2010 		self.__stringtableExported = False
  1983 
  2011 
  1984 		# The target name by default is the name of the stringtable without the extension
  2012 		# The target name by default is the name of the stringtable without the extension
  2167 
  2195 
  2168 		for i,var in enumerate(self.ResourceVariants):
  2196 		for i,var in enumerate(self.ResourceVariants):
  2169 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_TARGET_lower", self.__TARGET.lower()))
  2197 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_TARGET_lower", self.__TARGET.lower()))
  2170 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_REQUESTEDTARGETEXT", self.__TARGETEXT.lower()))
  2198 			self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_REQUESTEDTARGETEXT", self.__TARGETEXT.lower()))
  2171 
  2199 
       
  2200 		# Create Capability variable in one SET operation (more efficient than multiple appends)
       
  2201 		self.BuildVariant.AddOperation(raptor_data.Set("CAPABILITY"," ".join(self.capabilities)))
       
  2202 
  2172 		# Resolve combined capabilities as hex flags, for configurations that require them
  2203 		# Resolve combined capabilities as hex flags, for configurations that require them
  2173 		capabilityFlag1 = 0
  2204 		capabilityFlag1 = 0
  2174 		capabilityFlag2 = 0			# Always 0
  2205 		capabilityFlag2 = 0			# Always 0
  2175 
  2206 
  2176 		for capability in self.__capabilities:
  2207 		for capability in [c.lower() for c in self.capabilities]:
  2177 			invert = 0
  2208 			invert = 0
  2178 
  2209 
  2179 			if capability.startswith('-'):
  2210 			if capability.startswith('-'):
  2180 				invert = 0xffffffff
  2211 				invert = 0xffffffff
  2181 				capability = capability.lstrip('-')
  2212 				capability = capability.lstrip('-')
  2283 				resolvedDefFile = raptor_utilities.resolveSymbianPath(self.__defFileRoot, resolvedDefFile, 'DEFFILE', "", str(aBuildPlatform['EPOCROOT']))
  2314 				resolvedDefFile = raptor_utilities.resolveSymbianPath(self.__defFileRoot, resolvedDefFile, 'DEFFILE', "", str(aBuildPlatform['EPOCROOT']))
  2284 
  2315 
  2285 		return resolvedDefFile
  2316 		return resolvedDefFile
  2286 
  2317 
  2287 
  2318 
       
  2319 def CheckedGet(self, key, default = None):
       
  2320 	"""extract a value from an self and raise an exception if None.
       
  2321 
       
  2322 	An optional default can be set to replace a None value.
       
  2323 
       
  2324 	This function belongs in the Evaluator class logically. But
       
  2325 	Evaluator doesn't know how to raise a Metadata error. Since
       
  2326 	being able to raise a metadata error is the whole point of
       
  2327 	the method, it makes sense to adapt the Evaluator class from
       
  2328 	raptor_meta for the use of everything inside raptor_meta.
       
  2329 
       
  2330 	... so it will be added to the Evaluator class.
       
  2331 	"""
       
  2332 
       
  2333 	value = self.Get(key)
       
  2334 	if value == None:
       
  2335 		if default == None:
       
  2336 			raise MetaDataError("configuration " + self.buildUnit.name +
       
  2337 							    " has no variable " + key)
       
  2338 		else:
       
  2339 			return default
       
  2340 	return value
       
  2341 
       
  2342 raptor_data.Evaluator.CheckedGet = CheckedGet 
       
  2343 
       
  2344 
  2288 class MetaReader(object):
  2345 class MetaReader(object):
  2289 	"""Entry point class for Symbian metadata processing.
  2346 	"""Entry point class for Symbian metadata processing.
  2290 
  2347 
  2291 	Provides a means of integrating "traditional" Symbian metadata processing
  2348 	Provides a means of integrating "traditional" Symbian metadata processing
  2292 	with the new Raptor build system."""
  2349 	with the new Raptor build system."""
  2299 		self.ExportPlatforms = []
  2356 		self.ExportPlatforms = []
  2300 
  2357 
  2301 		# Get the version of CPP that we are using
  2358 		# Get the version of CPP that we are using
  2302 		metadata = self.__Raptor.cache.FindNamedVariant("meta")
  2359 		metadata = self.__Raptor.cache.FindNamedVariant("meta")
  2303 		evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) )
  2360 		evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) )
  2304 		self.__gnucpp = self.CheckValue(evaluator, "GNUCPP")
  2361 		self.__gnucpp = evaluator.CheckedGet("GNUCPP")
  2305 		self.__defaultplatforms = self.CheckValue(evaluator, "DEFAULT_PLATFORMS")
  2362 		self.__defaultplatforms = evaluator.CheckedGet("DEFAULT_PLATFORMS")
  2306 		self.__basedefaultplatforms = self.CheckValue(evaluator, "BASE_DEFAULT_PLATFORMS")
  2363 		self.__basedefaultplatforms = evaluator.CheckedGet("BASE_DEFAULT_PLATFORMS")
  2307 		self.__baseuserdefaultplatforms = self.CheckValue(evaluator, "BASE_USER_DEFAULT_PLATFORMS")
  2364 		self.__baseuserdefaultplatforms = evaluator.CheckedGet("BASE_USER_DEFAULT_PLATFORMS")
  2308 
  2365 
  2309 		# Only read each variant.cfg once
  2366 		# Only read each variant.cfg once
  2310 		variantCfgs = {}
  2367 		variantCfgs = {}
  2311 
  2368 
  2312 		# Group the list of configurations into "build platforms".
  2369 		# Group the list of configurations into "build platforms".
  2321 		# and VARIANT_HRH values. Each "build platform" has one associated
  2378 		# and VARIANT_HRH values. Each "build platform" has one associated
  2322 		# "export platform" but several "build platforms" can be associated
  2379 		# "export platform" but several "build platforms" can be associated
  2323 		# with the same "export platform".
  2380 		# with the same "export platform".
  2324 		exports = {}
  2381 		exports = {}
  2325 
  2382 
       
  2383 		self.__Raptor.Debug("MetaReader: configsToBuild:  %s", [b.name for b in configsToBuild])
  2326 		for buildConfig in configsToBuild:
  2384 		for buildConfig in configsToBuild:
  2327 			# get everything we need to know about the configuration
  2385 			# get everything we need to know about the configuration
  2328 			evaluator = self.__Raptor.GetEvaluator(None, buildConfig)
  2386 			evaluator = self.__Raptor.GetEvaluator(None, buildConfig)
  2329 
  2387 
  2330 			detail = {}
  2388 			detail = {}
  2331 			detail['PLATFORM'] = self.CheckValue(evaluator, "TRADITIONAL_PLATFORM")
  2389 			detail['PLATFORM'] = evaluator.CheckedGet("TRADITIONAL_PLATFORM")
  2332 			epocroot = self.CheckValue(evaluator, "EPOCROOT")
  2390 			epocroot = evaluator.CheckedGet("EPOCROOT")
  2333 			detail['EPOCROOT'] = generic_path.Path(epocroot)
  2391 			detail['EPOCROOT'] = generic_path.Path(epocroot)
  2334 
  2392 
  2335 			sbs_build_dir = self.CheckValue(evaluator, "SBS_BUILD_DIR")
  2393 			sbs_build_dir = evaluator.CheckedGet("SBS_BUILD_DIR")
  2336 			detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir)
  2394 			detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir)
  2337 			flm_export_dir = self.CheckValue(evaluator, "FLM_EXPORT_DIR")
  2395 			flm_export_dir = evaluator.CheckedGet("FLM_EXPORT_DIR")
  2338 			detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir)
  2396 			detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir)
  2339 			detail['CACHEID'] = flm_export_dir
  2397 			detail['CACHEID'] = flm_export_dir
  2340 			if raptor_utilities.getOSPlatform().startswith("win"):
  2398 			if raptor_utilities.getOSPlatform().startswith("win"):
  2341 				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.WINDOWS")
  2399 				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.WINDOWS")
  2342 			else:
  2400 			else:
  2343 				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.LINUX")
  2401 				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.LINUX")
  2344 
  2402 
  2345 			# Apply OS variant provided we are not ignoring this
  2403 			# Apply OS variant provided we are not ignoring this
  2346 			if not self.__Raptor.ignoreOsDetection:
  2404 			if not self.__Raptor.ignoreOsDetection:
  2347 				self.__Raptor.Debug("Automatic OS detection enabled.")
  2405 				self.__Raptor.Debug("Automatic OS detection enabled.")
  2348 				self.ApplyOSVariant(buildConfig, epocroot)
  2406 				self.ApplyOSVariant(buildConfig, epocroot)
  2350 				self.__Raptor.Debug("Automatic OS detection disabled.")
  2408 				self.__Raptor.Debug("Automatic OS detection disabled.")
  2351 
  2409 
  2352 			# is this a feature variant config or an ordinary variant
  2410 			# is this a feature variant config or an ordinary variant
  2353 			fv = evaluator.Get("FEATUREVARIANTNAME")
  2411 			fv = evaluator.Get("FEATUREVARIANTNAME")
  2354 			if fv:
  2412 			if fv:
  2355 				variantHdr = self.CheckValue(evaluator, "VARIANT_HRH")
  2413 				variantHdr = evaluator.CheckedGet("VARIANT_HRH")
  2356 				variantHRH = generic_path.Path(variantHdr)
  2414 				variantHRH = generic_path.Path(variantHdr)
  2357 				detail['ISFEATUREVARIANT'] = True
  2415 				detail['ISFEATUREVARIANT'] = True
  2358 			else:
  2416 			else:
  2359 				variantCfg = self.CheckValue(evaluator, "VARIANT_CFG")
  2417 				variantCfg = evaluator.CheckedGet("VARIANT_CFG")
  2360 				variantCfg = generic_path.Path(variantCfg)
  2418 				variantCfg = generic_path.Path(variantCfg)
  2361 				if not variantCfg in variantCfgs:
  2419 				if not variantCfg in variantCfgs:
  2362 					# get VARIANT_HRH from the variant.cfg file
  2420 					# get VARIANT_HRH from the variant.cfg file
  2363 					varCfg = getVariantCfgDetail(detail['EPOCROOT'], variantCfg)
  2421 					varCfg = getVariantCfgDetail(detail['EPOCROOT'], variantCfg)
  2364 					variantCfgs[variantCfg] = varCfg['VARIANT_HRH']
  2422 					variantCfgs[variantCfg] = varCfg['VARIANT_HRH']
  2369 				variantHRH = variantCfgs[variantCfg]
  2427 				variantHRH = variantCfgs[variantCfg]
  2370 				detail['ISFEATUREVARIANT'] = False
  2428 				detail['ISFEATUREVARIANT'] = False
  2371 
  2429 
  2372 			detail['VARIANT_HRH'] = variantHRH
  2430 			detail['VARIANT_HRH'] = variantHRH
  2373 			self.__Raptor.Info("'%s' uses variant hrh file '%s'", buildConfig.name, variantHRH)
  2431 			self.__Raptor.Info("'%s' uses variant hrh file '%s'", buildConfig.name, variantHRH)
  2374 			detail['SYSTEMINCLUDE'] = self.CheckValue(evaluator, "SYSTEMINCLUDE")
  2432 			detail['SYSTEMINCLUDE'] = evaluator.CheckedGet("SYSTEMINCLUDE")
  2375 
  2433 
  2376 			detail['METADEPS'] = [] # Dependency targets for all metadata files in this platform
       
  2377 
  2434 
  2378 			# find all the interface names we need
  2435 			# find all the interface names we need
  2379 			ifaceTypes = self.CheckValue(evaluator, "INTERFACE_TYPES")
  2436 			ifaceTypes = evaluator.CheckedGet("INTERFACE_TYPES")
  2380 			interfaces = ifaceTypes.split()
  2437 			interfaces = ifaceTypes.split()
  2381 
  2438 
  2382 			for iface in interfaces:
  2439 			for iface in interfaces:
  2383 				detail[iface] = self.CheckValue(evaluator, "INTERFACE." + iface)
  2440 				detail[iface] = evaluator.CheckedGet("INTERFACE." + iface)
  2384 
  2441 
  2385 			# not test code unless positively specified
  2442 			# not test code unless positively specified
  2386 			detail['TESTCODE'] = self.CheckValue(evaluator, "TESTCODE", "")
  2443 			detail['TESTCODE'] = evaluator.CheckedGet("TESTCODE", "")
  2387 
  2444 
  2388 			# make a key that identifies this platform uniquely
  2445 			# make a key that identifies this platform uniquely
  2389 			# - used to tell us whether we have done the pre-processing
  2446 			# - used to tell us whether we have done the pre-processing
  2390 			# we need already using another platform with compatible values.
  2447 			# we need already using another platform with compatible values.
  2391 
  2448 
  2452 
  2509 
  2453 		# one platform is picked as the "default" for extracting things
  2510 		# one platform is picked as the "default" for extracting things
  2454 		# that are supposedly platform independent (e.g. PRJ_PLATFORMS)
  2511 		# that are supposedly platform independent (e.g. PRJ_PLATFORMS)
  2455 		self.defaultPlatform = self.ExportPlatforms[0]
  2512 		self.defaultPlatform = self.ExportPlatforms[0]
  2456 
  2513 
  2457 	def CheckValue(self, evaluator, key, default = None):
  2514 
  2458 		"""extract a value from an evaluator and raise an exception if None.
  2515 	def ReadBldInfFiles(self, aComponentList, doexport, dobuild = True):
  2459 
       
  2460 		An optional default can be set to replace a None value."""
       
  2461 		value = evaluator.Get(key)
       
  2462 		if value == None:
       
  2463 			if default == None:
       
  2464 				raise MetaDataError("configuration " + evaluator.config.name +
       
  2465 								    " has no variable " + key)
       
  2466 			else:
       
  2467 				return default
       
  2468 		return value
       
  2469 
       
  2470 	def ReadBldInfFiles(self, aFileList, doExportOnly):
       
  2471 		"""Take a list of bld.inf files and return a list of build specs.
  2516 		"""Take a list of bld.inf files and return a list of build specs.
  2472 
  2517 
  2473 		The returned specification nodes will be suitable for all the build
  2518 		The returned specification nodes will be suitable for all the build
  2474 		configurations under consideration (using Filter nodes where required).
  2519 		configurations under consideration (using Filter nodes where required).
  2475 		"""
  2520 		"""
  2476 
  2521 
  2477 		# we need a Filter node per export platform
  2522 		# we need a Filter node per export platform
  2478 		exportNodes = []
  2523 		exportNodes = []
  2479 		for i,ep in enumerate(self.ExportPlatforms):
  2524 		for i,ep in enumerate(self.ExportPlatforms):
  2480 			filter = raptor_data.Filter("export_" + str(i))
  2525 			filter = raptor_data.Filter(name = "export_" + str(i))
  2481 
  2526 
  2482 			# what configurations is this node active for?
  2527 			# what configurations is this node active for?
  2483 			for config in ep['configs']:
  2528 			for config in ep['configs']:
  2484 				filter.AddConfigCondition(config.name)
  2529 				filter.AddConfigCondition(config.name)
  2485 
  2530 
  2486 			exportNodes.append(filter)
  2531 			exportNodes.append(filter)
  2487 
  2532 
  2488 		# we need a Filter node per build platform
  2533 		# we need a Filter node per build platform
  2489 		platformNodes = []
  2534 		platformNodes = []
  2490 		for i,bp in enumerate(self.BuildPlatforms):
  2535 		for i,bp in enumerate(self.BuildPlatforms):
  2491 			filter = raptor_data.Filter("build_" + str(i))
  2536 			filter = raptor_data.Filter(name = "build_" + str(i))
  2492 
  2537 
  2493 			# what configurations is this node active for?
  2538 			# what configurations is this node active for?
  2494 			for config in bp['configs']:
  2539 			for config in bp['configs']:
  2495 				filter.AddConfigCondition(config.name)
  2540 				filter.AddConfigCondition(config.name)
  2496 
  2541 
  2502 			filter.AddVariant(platformVar)
  2547 			filter.AddVariant(platformVar)
  2503 			platformNodes.append(filter)
  2548 			platformNodes.append(filter)
  2504 
  2549 
  2505 		# check that each bld.inf exists and add a Specification node for it
  2550 		# check that each bld.inf exists and add a Specification node for it
  2506 		# to the nodes of the export and build platforms that it supports.
  2551 		# to the nodes of the export and build platforms that it supports.
  2507 		for bif in aFileList:
  2552 		for c in aComponentList:
  2508 			if bif.isFile():
  2553 			if c.bldinf_filename.isFile():
  2509 				self.__Raptor.Info("Processing %s", str(bif))
  2554 				self.__Raptor.Info("Processing %s", str(c.bldinf_filename))
  2510 				try:
  2555 				try:
  2511 					self.AddComponentNodes(bif, exportNodes, platformNodes)
  2556 					self.AddComponentNodes(c, exportNodes, platformNodes)
  2512 
  2557 
  2513 				except MetaDataError, e:
  2558 				except MetaDataError, e:
  2514 					self.__Raptor.Error(e.Text, bldinf=str(bif))
  2559 					self.__Raptor.Error(e.Text, bldinf=str(c.bldinf_filename))
  2515 					if not self.__Raptor.keepGoing:
  2560 					if not self.__Raptor.keepGoing:
  2516 						return []
  2561 						return []
  2517 			else:
  2562 			else:
  2518 				self.__Raptor.Error("build info file does not exist", bldinf=str(bif))
  2563 				self.__Raptor.Error("build info file does not exist", bldinf=str(c.bldinf_filename))
  2519 				if not self.__Raptor.keepGoing:
  2564 				if not self.__Raptor.keepGoing:
  2520 					return []
  2565 					return []
  2521 
  2566 
  2522 		# now we have the top-level structure in place...
  2567 		# now we have the top-level structure in place...
  2523 		#
  2568 		#
  2545 
  2590 
  2546 		# we now need to process the EXPORTS for all the bld.inf nodes
  2591 		# we now need to process the EXPORTS for all the bld.inf nodes
  2547 		# before we can do anything else (because raptor itself must do
  2592 		# before we can do anything else (because raptor itself must do
  2548 		# some exports before the MMP files that include them can be
  2593 		# some exports before the MMP files that include them can be
  2549 		# processed).
  2594 		# processed).
  2550 		for i,p in enumerate(exportNodes):
  2595 		if doexport:
  2551 			exportPlatform = self.ExportPlatforms[i]
  2596 			for i,p in enumerate(exportNodes):
  2552 			for s in p.GetChildSpecs():
  2597 				exportPlatform = self.ExportPlatforms[i]
  2553 				try:
  2598 				for s in p.GetChildSpecs():
  2554 					self.ProcessExports(s, exportPlatform)
  2599 					try:
  2555 
  2600 						self.ProcessExports(s, exportPlatform)
  2556 				except MetaDataError, e:
  2601 
  2557 					self.__Raptor.Error("%s",e.Text)
  2602 					except MetaDataError, e:
  2558 					if not self.__Raptor.keepGoing:
  2603 						self.__Raptor.Error("%s",e.Text)
  2559 						return []
  2604 						if not self.__Raptor.keepGoing:
       
  2605 							return []
       
  2606 		else:
       
  2607 			self.__Raptor.Info("Not Processing Exports (--noexport enabled)")
  2560 
  2608 
  2561 		# this is a switch to return the function at this point if export
  2609 		# this is a switch to return the function at this point if export
  2562 		# only option is specified in the run
  2610 		# only option is specified in the run
  2563 		if (self.__Raptor.doExportOnly):
  2611 		if dobuild is not True:
  2564 			self.__Raptor.Info("Processing Exports only")
  2612 			self.__Raptor.Info("Processing Exports only")
  2565 			return[]
  2613 			return[]
  2566 
  2614 
  2567 		# after exports are done we can look to see if there are any
  2615 		# after exports are done we can look to see if there are any
  2568 		# new Interfaces which can be used for EXTENSIONS. Make sure
  2616 		# new Interfaces which can be used for EXTENSIONS. Make sure
  2601 	def ModuleName(self,aBldInfPath):
  2649 	def ModuleName(self,aBldInfPath):
  2602 		"""Calculate the name of the ROM/emulator batch files that run the tests"""
  2650 		"""Calculate the name of the ROM/emulator batch files that run the tests"""
  2603 
  2651 
  2604 		def LeftPortionOf(pth,sep):
  2652 		def LeftPortionOf(pth,sep):
  2605 			""" Internal function to return portion of str that is to the left of sep. 
  2653 			""" Internal function to return portion of str that is to the left of sep. 
  2606 			The partition is case-insentive."""
  2654 			The split is case-insensitive."""
  2607 			length = len((pth.lower().partition(sep.lower()))[0])
  2655 			length = len((pth.lower().split(sep.lower()))[0])
  2608 			return pth[0:length]
  2656 			return pth[0:length]
  2609 			
  2657 			
  2610 		modulePath = LeftPortionOf(LeftPortionOf(os.path.dirname(aBldInfPath), "group"), "ongoing")
  2658 		modulePath = LeftPortionOf(LeftPortionOf(os.path.dirname(aBldInfPath), "group"), "ongoing")
  2611 		moduleName = os.path.basename(modulePath.strip("/"))
  2659 		moduleName = os.path.basename(modulePath.strip("/"))
  2612 		
  2660 		
  2615 		if moduleName == "" or moduleName.endswith(":"):
  2663 		if moduleName == "" or moduleName.endswith(":"):
  2616 			moduleName = "module"
  2664 			moduleName = "module"
  2617 		return moduleName
  2665 		return moduleName
  2618 
  2666 
  2619 
  2667 
  2620 	def AddComponentNodes(self, buildFile, exportNodes, platformNodes):
  2668 	def AddComponentNodes(self, component, exportNodes, platformNodes):	
  2621 		"""Add Specification nodes for a bld.inf to the appropriate platforms."""
  2669 		"""Add Specification nodes for a bld.inf to the appropriate platforms."""
  2622 		bldInfFile = BldInfFile(buildFile, self.__gnucpp, self.__Raptor)
  2670 		bldInfFile = BldInfFile(component.bldinf_filename, self.__gnucpp, component.depfiles, self.__Raptor)
  2623 
  2671 		component.bldinf = bldInfFile 
  2624 		specName = self.getSpecName(buildFile, fullPath=True)
  2672 
  2625 
  2673 		specName = getSpecName(component.bldinf_filename, fullPath=True)
  2626 		if isinstance(buildFile, raptor_xml.SystemModelComponent):
  2674 
       
  2675 		if isinstance(component.bldinf, raptor_xml.SystemModelComponent):
  2627 			# this component came from a system_definition.xml
  2676 			# this component came from a system_definition.xml
  2628 			layer = buildFile.GetContainerName("layer")
  2677 			layer = component.bldinf.GetContainerName("layer")
  2629 			component = buildFile.GetContainerName("component")
  2678 			componentName = component.bldinf.GetContainerName("component")
  2630 		else:
  2679 		else:
  2631 			# this is a plain old bld.inf file from the command-line
  2680 			# this is a plain old bld.inf file from the command-line
  2632 			layer = ""
  2681 			layer = ""
  2633 			component = ""
  2682 			componentName = ""
  2634 
  2683 
  2635 		# exports are independent of build platform
  2684 		# exports are independent of build platform
  2636 		for i,ep in enumerate(self.ExportPlatforms):
  2685 		for i,ep in enumerate(self.ExportPlatforms):
  2637 			specNode = raptor_data.Specification(specName)
  2686 			specNode = raptor_data.Specification(name = specName)
  2638 
  2687 
  2639 			# keep the BldInfFile object for later
  2688 			# keep the BldInfFile object for later
  2640 			specNode.bldinf = bldInfFile
  2689 			specNode.component = component
  2641 
  2690 
  2642 			# add some basic data in a component-wide variant
  2691 			# add some basic data in a component-wide variant
  2643 			var = raptor_data.Variant()
  2692 			var = raptor_data.Variant(name='component-wide')
  2644 			var.AddOperation(raptor_data.Set("COMPONENT_META", str(buildFile)))
  2693 			var.AddOperation(raptor_data.Set("COMPONENT_META", str(component.bldinf_filename)))
  2645 			var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
  2694 			var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
  2646 			var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2695 			var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2647 			specNode.AddVariant(var)
  2696 			specNode.AddVariant(var)
  2648 
  2697 
  2649 			# add this bld.inf Specification to the export platform
  2698 			# add this bld.inf Specification to the export platform
  2650 			exportNodes[i].AddChild(specNode)
  2699 			exportNodes[i].AddChild(specNode)
       
  2700 			component.exportspecs.append(specNode)
  2651 
  2701 
  2652 		# get the relevant build platforms
  2702 		# get the relevant build platforms
  2653 		listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform)
  2703 		listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform)
  2654 		platforms = getBuildableBldInfBuildPlatforms(listedPlatforms,
  2704 		platforms = getBuildableBldInfBuildPlatforms(listedPlatforms,
  2655 													self.__defaultplatforms,
  2705 								self.__defaultplatforms,
  2656 													self.__basedefaultplatforms,
  2706 								self.__basedefaultplatforms,
  2657 													self.__baseuserdefaultplatforms)
  2707 								self.__baseuserdefaultplatforms)
  2658 
  2708 
  2659 
  2709 
  2660 
  2710 		outputDir = BldInfFile.outputPathFragment(component.bldinf_filename)
  2661 		outputDir = BldInfFile.outputPathFragment(buildFile)
       
  2662 
  2711 
  2663 		# Calculate "module name"
  2712 		# Calculate "module name"
  2664 		modulename = self.ModuleName(str(buildFile))
  2713 		modulename = self.ModuleName(str(component.bldinf_filename))
  2665 
  2714 
  2666 		for i,bp in enumerate(self.BuildPlatforms):
  2715 		for i,bp in enumerate(self.BuildPlatforms):
       
  2716 			plat = bp['PLATFORM']
  2667 			if bp['PLATFORM'] in platforms:
  2717 			if bp['PLATFORM'] in platforms:
  2668 				specNode = raptor_data.Specification(specName)
  2718 				specNode = raptor_data.Specification(name = specName)
  2669 
  2719 
  2670 				# keep the BldInfFile object for later
  2720 				# remember what component this spec node comes from for later
  2671 				specNode.bldinf = bldInfFile
  2721 				specNode.component = component
  2672 
  2722 
  2673 				# add some basic data in a component-wide variant
  2723 				# add some basic data in a component-wide variant
  2674 				var = raptor_data.Variant()
  2724 				var = raptor_data.Variant(name='component-wide-settings-' + plat)
  2675 				var.AddOperation(raptor_data.Set("COMPONENT_META",str(buildFile)))
  2725 				var.AddOperation(raptor_data.Set("COMPONENT_META",str(component.bldinf_filename)))
  2676 				var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
  2726 				var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
  2677 				var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2727 				var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2678 				var.AddOperation(raptor_data.Set("MODULE", modulename))
  2728 				var.AddOperation(raptor_data.Set("MODULE", modulename))
  2679 				var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/'))
  2729 				var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/'))
  2680 				var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/'))
  2730 				var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/'))
  2681 				var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/'))
  2731 				var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/'))
  2682 
  2732 
  2683 				var.AddOperation(raptor_data.Set("TEST_OPTION", specNode.bldinf.getRomTestType(bp)))
  2733 				var.AddOperation(raptor_data.Set("TEST_OPTION", component.bldinf.getRomTestType(bp)))
  2684 				specNode.AddVariant(var)
  2734 				specNode.AddVariant(var)
  2685 
  2735 
  2686 				# add this bld.inf Specification to the build platform
  2736 				# add this bld.inf Specification to the build platform
  2687 				platformNodes[i].AddChild(specNode)
  2737 				platformNodes[i].AddChild(specNode)
       
  2738 				# also attach it into the component
       
  2739 				component.specs.append(specNode)
  2688 
  2740 
  2689 	def ProcessExports(self, componentNode, exportPlatform):
  2741 	def ProcessExports(self, componentNode, exportPlatform):
  2690 		"""Do the exports for a given platform and skeleton bld.inf node.
  2742 		"""Do the exports for a given platform and skeleton bld.inf node.
  2691 
  2743 
  2692 		This will actually perform exports as certain types of files (.mmh)
  2744 		This will actually perform exports as certain types of files (.mmh)
  2694 		(and parts of other bld.inf nodes) can be processed.
  2746 		(and parts of other bld.inf nodes) can be processed.
  2695 
  2747 
  2696 		[some MMP files #include exported .mmh files]
  2748 		[some MMP files #include exported .mmh files]
  2697 		"""
  2749 		"""
  2698 		if exportPlatform["TESTCODE"]:
  2750 		if exportPlatform["TESTCODE"]:
  2699 			exports = componentNode.bldinf.getTestExports(exportPlatform)
  2751 			exports = componentNode.component.bldinf.getTestExports(exportPlatform)
  2700 		else:
  2752 		else:
  2701 			exports = componentNode.bldinf.getExports(exportPlatform)
  2753 			exports = componentNode.component.bldinf.getExports(exportPlatform)
  2702 
  2754 
  2703 		self.__Raptor.Debug("%i exports for %s",
  2755 		self.__Raptor.Debug("%i exports for %s",
  2704 							len(exports), str(componentNode.bldinf.filename))
  2756 							len(exports), str(componentNode.component.bldinf.filename))
  2705 		if exports:
  2757 		if exports:
  2706 
  2758 
  2707 			# each export is either a 'copy' or 'unzip'
  2759 			# each export is either a 'copy' or 'unzip'
  2708 			# maybe we should trap multiple exports to the same location here?
  2760 			# maybe we should trap multiple exports to the same location here?
  2709 			epocroot = str(exportPlatform["EPOCROOT"])
  2761 			epocroot = str(exportPlatform["EPOCROOT"])
  2710 			bldinf_filename = str(componentNode.bldinf.filename)
  2762 			bldinf_filename = str(componentNode.component.bldinf.filename)
  2711 			exportwhatlog="<whatlog bldinf='%s' mmp='' config=''>\n" % bldinf_filename
  2763 			exportwhatlog="<whatlog bldinf='%s' mmp='' config=''>\n" % bldinf_filename
  2712 			for export in exports:
  2764 			for export in exports:
  2713 				expSrc = export.getSource()
  2765 				expSrc = export.getSource()
  2714 				expDstList = export.getDestination() # Might not be a list in all circumstances
  2766 				expDstList = export.getDestination() # Might not be a list in all circumstances
  2715 
  2767 
  2728 					try:
  2780 					try:
  2729 						if export.getAction() == "copy":
  2781 						if export.getAction() == "copy":
  2730 							# export the file
  2782 							# export the file
  2731 							exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename)
  2783 							exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename)
  2732 						else:
  2784 						else:
  2733 							# unzip the zip
       
  2734 							exportwhatlog += ("<archive zipfile='" + str(fromFile) + "'>\n")
  2785 							exportwhatlog += ("<archive zipfile='" + str(fromFile) + "'>\n")
  2735 							members = self.UnzipExport(fromFile, toFile,
  2786 							members = self.UnzipExport(fromFile, toFile,
  2736 									str(exportPlatform['SBS_BUILD_DIR']),
  2787 									str(exportPlatform['SBS_BUILD_DIR']),
  2737 									bldinf_filename)
  2788 									bldinf_filename)
  2738 							if members != None:
  2789 							if members != None:
  2876 						if os.path.exists(expfilename):
  2927 						if os.path.exists(expfilename):
  2877 							os.chmod(expfilename,stat.S_IREAD | stat.S_IWRITE)
  2928 							os.chmod(expfilename,stat.S_IREAD | stat.S_IWRITE)
  2878 						expfile = open(expfilename, 'wb')
  2929 						expfile = open(expfilename, 'wb')
  2879 						expfile.write(exportzip.read(file))
  2930 						expfile.write(exportzip.read(file))
  2880 						expfile.close()
  2931 						expfile.close()
       
  2932 						
       
  2933 						# Resurrect any file execution permissions present in the archived version
       
  2934 						if (exportzip.getinfo(file).external_attr >> 16L) & 0100:
       
  2935 							os.chmod(expfilename, stat.S_IMODE(os.stat(expfilename).st_mode) | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)						
       
  2936 						
  2881 						# Each file keeps its modified time the same as what it was before unzipping
  2937 						# Each file keeps its modified time the same as what it was before unzipping
  2882 						accesstime = time.time()
  2938 						accesstime = time.time()
  2883 						datetime = exportzip.getinfo(file).date_time
  2939 						datetime = exportzip.getinfo(file).date_time
  2884 						timeTuple=(int(datetime[0]), int(datetime[1]), int(datetime[2]), int(datetime[3]), \
  2940 						timeTuple=(int(datetime[0]), int(datetime[1]), int(datetime[2]), int(datetime[3]), \
  2885 									int(datetime[4]), int(datetime[5]), int(0), int(0), int(0))
  2941 									int(datetime[4]), int(datetime[5]), int(0), int(0), int(0))
  2915 		"""
  2971 		"""
  2916 		if buildPlatform["ISFEATUREVARIANT"]:
  2972 		if buildPlatform["ISFEATUREVARIANT"]:
  2917 			return	# feature variation does not run extensions at all
  2973 			return	# feature variation does not run extensions at all
  2918 		
  2974 		
  2919 		if buildPlatform["TESTCODE"]:
  2975 		if buildPlatform["TESTCODE"]:
  2920 			extensions = componentNode.bldinf.getTestExtensions(buildPlatform)
  2976 			extensions = componentNode.component.bldinf.getTestExtensions(buildPlatform)
  2921 		else:
  2977 		else:
  2922 			extensions = componentNode.bldinf.getExtensions(buildPlatform)
  2978 			extensions = componentNode.component.bldinf.getExtensions(buildPlatform)
  2923 
  2979 
  2924 		self.__Raptor.Debug("%i template extension makefiles for %s",
  2980 		self.__Raptor.Debug("%i template extension makefiles for %s",
  2925 							len(extensions), str(componentNode.bldinf.filename))
  2981 							len(extensions), str(componentNode.component.bldinf.filename))
  2926 
  2982 
  2927 		for i,extension in enumerate(extensions):
  2983 		for i,extension in enumerate(extensions):
  2928 			if self.__Raptor.projects:
  2984 			if self.__Raptor.projects:
  2929 				if not extension.nametag in self.__Raptor.projects:
  2985 				if not extension.nametag in self.__Raptor.projects:
  2930 					self.__Raptor.Debug("Skipping %s", extension.getMakefile())
  2986 					self.__Raptor.Debug("Skipping %s", extension.getMakefile())
  2999 		This happens after exports have been handled.
  3055 		This happens after exports have been handled.
  3000 		"""
  3056 		"""
  3001 		gnuList = []
  3057 		gnuList = []
  3002 		makefileList = []
  3058 		makefileList = []
  3003 
  3059 
       
  3060 
       
  3061 		component = componentNode.component
       
  3062 
       
  3063 
  3004 		if buildPlatform["TESTCODE"]:
  3064 		if buildPlatform["TESTCODE"]:
  3005 			MMPList = componentNode.bldinf.getTestMMPList(buildPlatform)
  3065 			MMPList = component.bldinf.getTestMMPList(buildPlatform)
  3006 		else:
  3066 		else:
  3007 			MMPList = componentNode.bldinf.getMMPList(buildPlatform)
  3067 			MMPList = component.bldinf.getMMPList(buildPlatform)
  3008 
  3068 
  3009 		bldInfFile = componentNode.bldinf.filename
  3069 		bldInfFile = component.bldinf.filename
  3010 
  3070 
  3011 		for mmpFileEntry in MMPList['mmpFileList']:
  3071 		for mmpFileEntry in MMPList['mmpFileList']:
       
  3072 			component.AddMMP(mmpFileEntry.filename) # Tell the component another mmp is specified (for this platform)
       
  3073 
  3012 			projectname = mmpFileEntry.filename.File().lower()
  3074 			projectname = mmpFileEntry.filename.File().lower()
  3013 
  3075 
  3014 			if self.__Raptor.projects:
  3076 			if self.__Raptor.projects:
  3015 				if not projectname in self.__Raptor.projects:
  3077 				if not projectname in self.__Raptor.projects:
  3016 					self.__Raptor.Debug("Skipping %s", str(mmpFileEntry.filename))
  3078 					self.__Raptor.Debug("Skipping %s", str(mmpFileEntry.filename))
  3024 				self.__Raptor.Error("Can't find mmp file '%s'", str(mmpFileEntry.filename), bldinf=str(bldInfFile))
  3086 				self.__Raptor.Error("Can't find mmp file '%s'", str(mmpFileEntry.filename), bldinf=str(bldInfFile))
  3025 				continue
  3087 				continue
  3026 
  3088 
  3027 			mmpFile = MMPFile(foundmmpfile,
  3089 			mmpFile = MMPFile(foundmmpfile,
  3028 								   self.__gnucpp,
  3090 								   self.__gnucpp,
  3029 								   bldinf = componentNode.bldinf,
  3091 								   component.bldinf,
       
  3092 								   component.depfiles,
  3030 								   log = self.__Raptor)
  3093 								   log = self.__Raptor)
  3031 
  3094 
  3032 			mmpFilename = mmpFile.filename
  3095 			mmpFilename = mmpFile.filename
  3033 
  3096 
  3034 			self.__Raptor.Info("Processing %s for platform %s",
  3097 			self.__Raptor.Info("Processing %s for platform %s",
  3058 			# feature variation only processes FEATUREVARIANT binaries
  3121 			# feature variation only processes FEATUREVARIANT binaries
  3059 			if buildPlatform["ISFEATUREVARIANT"] and not backend.featureVariant:
  3122 			if buildPlatform["ISFEATUREVARIANT"] and not backend.featureVariant:
  3060 				continue
  3123 				continue
  3061 			
  3124 			
  3062 			# now build the specification tree
  3125 			# now build the specification tree
  3063 			mmpSpec = raptor_data.Specification(self.getSpecName(mmpFilename))
  3126 			mmpSpec = raptor_data.Specification(generic_path.Path(getSpecName(mmpFilename)))
  3064 			var = backend.BuildVariant
  3127 			var = backend.BuildVariant
  3065 
  3128 
  3066 			var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename)))
  3129 			var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename)))
  3067 
  3130 
  3068 			# If it is a TESTMMPFILE section, the FLM needs to know about it
  3131 			# If it is a TESTMMPFILE section, the FLM needs to know about it
  3094 								    bldinf=str(bldInfFile))
  3157 								    bldinf=str(bldInfFile))
  3095 				continue
  3158 				continue
  3096 
  3159 
  3097 			# Although not part of the MMP, some MMP-based build specs additionally require knowledge of their
  3160 			# Although not part of the MMP, some MMP-based build specs additionally require knowledge of their
  3098 			# container bld.inf exported headers
  3161 			# container bld.inf exported headers
  3099 			for export in componentNode.bldinf.getExports(buildPlatform):
  3162 			for export in componentNode.component.bldinf.getExports(buildPlatform):
  3100 				destination = export.getDestination()
  3163 				destination = export.getDestination()
  3101 				if isinstance(destination, list):
  3164 				if isinstance(destination, list):
  3102 					exportfile = str(destination[0])
  3165 					exportfile = str(destination[0])
  3103 				else:
  3166 				else:
  3104 					exportfile = str(destination)
  3167 					exportfile = str(destination)
  3107 					var.AddOperation(raptor_data.Append("EXPORTHEADERS", str(exportfile)))
  3170 					var.AddOperation(raptor_data.Append("EXPORTHEADERS", str(exportfile)))
  3108 
  3171 
  3109 			# now we have something worth adding to the component
  3172 			# now we have something worth adding to the component
  3110 			mmpSpec.AddVariant(var)
  3173 			mmpSpec.AddVariant(var)
  3111 			componentNode.AddChild(mmpSpec)
  3174 			componentNode.AddChild(mmpSpec)
       
  3175 			
       
  3176 			# if there are APPLY variants then add them to the mmpSpec too
       
  3177 			for applyVar in backend.ApplyVariants:
       
  3178 				try:
       
  3179 					mmpSpec.AddVariant(self.__Raptor.cache.FindNamedVariant(applyVar))
       
  3180 				except KeyError:
       
  3181 					self.__Raptor.Error("APPLY unknown variant '%s' in %s",
       
  3182 								        applyVar,
       
  3183 								        str(mmpFileEntry.filename),
       
  3184 								        bldinf=str(bldInfFile))
  3112 
  3185 
  3113 			# resources, stringtables and bitmaps are sub-nodes of this project
  3186 			# resources, stringtables and bitmaps are sub-nodes of this project
  3114 			# (do not add these for feature variant builds)
  3187 			# (do not add these for feature variant builds)
  3115 			
  3188 			
  3116 			if not buildPlatform["ISFEATUREVARIANT"]:
  3189 			if not buildPlatform["ISFEATUREVARIANT"]:
  3150 					continue
  3223 					continue
  3151 				elif projectname in self.projectList:
  3224 				elif projectname in self.projectList:
  3152 					self.projectList.remove(projectname)
  3225 					self.projectList.remove(projectname)
  3153 
  3226 
  3154 			self.__Raptor.Debug("%i gnumakefile extension makefiles for %s",
  3227 			self.__Raptor.Debug("%i gnumakefile extension makefiles for %s",
  3155 						len(gnuList), str(componentNode.bldinf.filename))
  3228 						len(gnuList), str(componentNode.component.bldinf.filename))
  3156 			var = raptor_data.Variant()
  3229 			var = raptor_data.Variant()
  3157 			gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName()))
  3230 			gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName()))
  3158 			interface = buildPlatform["ext_makefile"]
  3231 			interface = buildPlatform["ext_makefile"]
  3159 			gnuSpec.SetInterface(interface)
  3232 			gnuSpec.SetInterface(interface)
  3160 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), g.getMakefileName())
  3233 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), g.getMakefileName())
  3182 					continue
  3255 					continue
  3183 				elif projectname in self.projectList:
  3256 				elif projectname in self.projectList:
  3184 					projectList.remove(projectname)
  3257 					projectList.remove(projectname)
  3185 
  3258 
  3186 			self.__Raptor.Debug("%i makefile extension makefiles for %s",
  3259 			self.__Raptor.Debug("%i makefile extension makefiles for %s",
  3187 						len(makefileList), str(componentNode.bldinf.filename))
  3260 						len(makefileList), str(componentNode.component.bldinf.filename))
  3188 			var = raptor_data.Variant()
  3261 			var = raptor_data.Variant()
  3189 			gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName()))
  3262 			gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName()))
  3190 			interface = buildPlatform["ext_makefile"]
  3263 			interface = buildPlatform["ext_makefile"]
  3191 			gnuSpec.SetInterface(interface)
  3264 			gnuSpec.SetInterface(interface)
  3192 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), m.getMakefileName())
  3265 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), m.getMakefileName())
  3203 				value = value.replace('$/', '/').replace('$;', ':')
  3276 				value = value.replace('$/', '/').replace('$;', ':')
  3204 				var.AddOperation(raptor_data.Set(standardVariable, value))
  3277 				var.AddOperation(raptor_data.Set(standardVariable, value))
  3205 			gnuSpec.AddVariant(var)
  3278 			gnuSpec.AddVariant(var)
  3206 			componentNode.AddChild(gnuSpec)
  3279 			componentNode.AddChild(gnuSpec)
  3207 
  3280 
  3208 	def getSpecName(self, aFileRoot, fullPath=False):
       
  3209 		"""Returns a build spec name: this is the file root (full path
       
  3210 		or simple file name) made safe for use as a file name."""
       
  3211 
       
  3212 		if fullPath:
       
  3213 			specName = str(aFileRoot).replace("/","_")
       
  3214 			specName = specName.replace(":","")
       
  3215 		else:
       
  3216 			specName = aFileRoot.File()
       
  3217 
       
  3218 		return specName.lower()
       
  3219 
  3281 
  3220 	def ApplyOSVariant(self, aBuildUnit, aEpocroot):
  3282 	def ApplyOSVariant(self, aBuildUnit, aEpocroot):
  3221 		# Form path to kif.xml and path to buildinfo.txt
  3283 		# Form path to kif.xml and path to buildinfo.txt
  3222 		kifXmlPath = generic_path.Join(aEpocroot, "epoc32", "data","kif.xml")
  3284 		kifXmlPath = generic_path.Join(aEpocroot, "epoc32", "data","kif.xml")
  3223 		buildInfoTxtPath = generic_path.Join(aEpocroot, "epoc32", "data","buildinfo.txt")
  3285 		buildInfoTxtPath = generic_path.Join(aEpocroot, "epoc32", "data","buildinfo.txt")