sbsv2/raptor/python/raptor_meta.py
changeset 44 cf0c187b284a
parent 2 86356a777616
parent 32 fdfc59a2ae7e
child 56 c02a2a09d864
equal deleted inserted replaced
2:86356a777616 44:cf0c187b284a
   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]))
  1448 				# the major version number
  1475 				# the major version number
  1449 				major = int(version[0],10)
  1476 				major = int(version[0],10)
  1450 
  1477 
  1451 				# add in the minor number
  1478 				# add in the minor number
  1452 				minor = 0
  1479 				minor = 0
  1453 				if len(version) >  1 and version[2] is not None:
  1480 				if version[1] is not None:
  1454 					minor = int(version[2],10)
  1481 					minor = int(version[2],10)
       
  1482 				else:
       
  1483 					self.__Raptor.Warn("VERSION (%s) missing '.minor' in %s, using '.0'" % (toks[1],self.__currentMmpFile))
  1455 
  1484 
  1456 				self.__versionhex = "%04x%04x" % (major, minor)
  1485 				self.__versionhex = "%04x%04x" % (major, minor)
  1457 				self.BuildVariant.AddOperation(raptor_data.Set(varname, "%d.%d" %(major, minor)))
  1486 				self.BuildVariant.AddOperation(raptor_data.Set(varname, "%d.%d" %(major, minor)))
  1458 				self.BuildVariant.AddOperation(raptor_data.Set(varname+"HEX", self.__versionhex))
  1487 				self.BuildVariant.AddOperation(raptor_data.Set(varname+"HEX", self.__versionhex))
  1459 				self.__debug("Set "+toks[0]+"  OPTION to " + toks[1])
  1488 				self.__debug("Set "+toks[0]+"  OPTION to " + toks[1])
  1515 				toks1 = str(toks[1]).replace("\\","/")
  1544 				toks1 = str(toks[1]).replace("\\","/")
  1516 				if toks1.find(","):
  1545 				if toks1.find(","):
  1517 					toks1 = re.sub("[,'\[\]]", "", toks1).replace("//","/")
  1546 					toks1 = re.sub("[,'\[\]]", "", toks1).replace("//","/")
  1518 				self.__debug("Set "+toks[0]+" to " + toks1)
  1547 				self.__debug("Set "+toks[0]+" to " + toks1)
  1519 				self.BuildVariant.AddOperation(raptor_data.Set(varname,toks1))
  1548 				self.BuildVariant.AddOperation(raptor_data.Set(varname,toks1))
  1520 
  1549 		elif varname=='APPLY':
       
  1550 			self.ApplyVariants.append(toks[1])
  1521 		else:
  1551 		else:
  1522 			self.__debug("Set "+toks[0]+" to " + str(toks[1]))
  1552 			self.__debug("Set "+toks[0]+" to " + str(toks[1]))
  1523 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(toks[1])))
  1553 			self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(toks[1])))
  1524 
  1554 
  1525 			if varname=='LINKAS':
  1555 			if varname=='LINKAS':
  1763 					# be a replacement to consider
  1793 					# be a replacement to consider
  1764 					search = match
  1794 					search = match
  1765 					replace = ""
  1795 					replace = ""
  1766 					if len(matches):
  1796 					if len(matches):
  1767 						replace = matches.pop()
  1797 						replace = matches.pop()
  1768 					
  1798 
  1769 					searchReplacePairs.append('%s<->%s' % (search, replace))
  1799 					searchReplacePairs.append('%s<->%s' % (search, replace))
  1770 
  1800 
  1771 			# Replace spaces to maintain word-based grouping in downstream makefile lists
  1801 			# Replace spaces to maintain word-based grouping in downstream makefile lists
  1772 			for i in range(0,len(searchReplacePairs)):
  1802 			for i in range(0,len(searchReplacePairs)):
  1773 				searchReplacePairs[i] = searchReplacePairs[i].replace(' ','%20')
  1803 				searchReplacePairs[i] = searchReplacePairs[i].replace(' ','%20')
  1882 
  1912 
  1883 	def doStartBitmap(self,s,loc,toks):
  1913 	def doStartBitmap(self,s,loc,toks):
  1884 		self.__currentLineNumber += 1
  1914 		self.__currentLineNumber += 1
  1885 		self.__debug("Start BITMAP "+toks[1])
  1915 		self.__debug("Start BITMAP "+toks[1])
  1886 
  1916 
  1887 		self.__currentBitmapVariant = raptor_data.Variant(toks[1].replace('.','_'))
  1917 		self.__currentBitmapVariant = raptor_data.Variant(name = toks[1].replace('.','_'))
  1888 		# Use BMTARGET and BMTARGET_lower because that prevents
  1918 		# Use BMTARGET and BMTARGET_lower because that prevents
  1889 		# confusion with the TARGET and TARGET_lower of our parent MMP
  1919 		# confusion with the TARGET and TARGET_lower of our parent MMP
  1890 		# when setting the OUTPUTPATH.  This in turn allows us to
  1920 		# when setting the OUTPUTPATH.  This in turn allows us to
  1891 		# not get tripped up by multiple mbms being generated with
  1921 		# not get tripped up by multiple mbms being generated with
  1892 		# the same name to the same directory.
  1922 		# the same name to the same directory.
  1972 
  2002 
  1973 		self.__debug("sourcepath: " + self.__sourcepath)
  2003 		self.__debug("sourcepath: " + self.__sourcepath)
  1974 		self.__debug("stringtable: " + toks[1])
  2004 		self.__debug("stringtable: " + toks[1])
  1975 		self.__debug("adjusted stringtable source=" + source)
  2005 		self.__debug("adjusted stringtable source=" + source)
  1976 
  2006 
  1977 		self.__currentStringTableVariant = raptor_data.Variant(uniqname)
  2007 		self.__currentStringTableVariant = raptor_data.Variant(name = uniqname)
  1978 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source))
  2008 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source))
  1979 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", ""))
  2009 		self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", ""))
  1980 		self.__stringtableExported = False
  2010 		self.__stringtableExported = False
  1981 
  2011 
  1982 		# 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
  2165 
  2195 
  2166 		for i,var in enumerate(self.ResourceVariants):
  2196 		for i,var in enumerate(self.ResourceVariants):
  2167 			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()))
  2168 			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()))
  2169 
  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 
  2170 		# Resolve combined capabilities as hex flags, for configurations that require them
  2203 		# Resolve combined capabilities as hex flags, for configurations that require them
  2171 		capabilityFlag1 = 0
  2204 		capabilityFlag1 = 0
  2172 		capabilityFlag2 = 0			# Always 0
  2205 		capabilityFlag2 = 0			# Always 0
  2173 
  2206 
  2174 		for capability in self.__capabilities:
  2207 		for capability in [c.lower() for c in self.capabilities]:
  2175 			invert = 0
  2208 			invert = 0
  2176 
  2209 
  2177 			if capability.startswith('-'):
  2210 			if capability.startswith('-'):
  2178 				invert = 0xffffffff
  2211 				invert = 0xffffffff
  2179 				capability = capability.lstrip('-')
  2212 				capability = capability.lstrip('-')
  2281 				resolvedDefFile = raptor_utilities.resolveSymbianPath(self.__defFileRoot, resolvedDefFile, 'DEFFILE', "", str(aBuildPlatform['EPOCROOT']))
  2314 				resolvedDefFile = raptor_utilities.resolveSymbianPath(self.__defFileRoot, resolvedDefFile, 'DEFFILE', "", str(aBuildPlatform['EPOCROOT']))
  2282 
  2315 
  2283 		return resolvedDefFile
  2316 		return resolvedDefFile
  2284 
  2317 
  2285 
  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 
  2286 class MetaReader(object):
  2345 class MetaReader(object):
  2287 	"""Entry point class for Symbian metadata processing.
  2346 	"""Entry point class for Symbian metadata processing.
  2288 
  2347 
  2289 	Provides a means of integrating "traditional" Symbian metadata processing
  2348 	Provides a means of integrating "traditional" Symbian metadata processing
  2290 	with the new Raptor build system."""
  2349 	with the new Raptor build system."""
  2297 		self.ExportPlatforms = []
  2356 		self.ExportPlatforms = []
  2298 
  2357 
  2299 		# Get the version of CPP that we are using
  2358 		# Get the version of CPP that we are using
  2300 		metadata = self.__Raptor.cache.FindNamedVariant("meta")
  2359 		metadata = self.__Raptor.cache.FindNamedVariant("meta")
  2301 		evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) )
  2360 		evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) )
  2302 		self.__gnucpp = self.CheckValue(evaluator, "GNUCPP")
  2361 		self.__gnucpp = evaluator.CheckedGet("GNUCPP")
  2303 		self.__defaultplatforms = self.CheckValue(evaluator, "DEFAULT_PLATFORMS")
  2362 		self.__defaultplatforms = evaluator.CheckedGet("DEFAULT_PLATFORMS")
  2304 		self.__basedefaultplatforms = self.CheckValue(evaluator, "BASE_DEFAULT_PLATFORMS")
  2363 		self.__basedefaultplatforms = evaluator.CheckedGet("BASE_DEFAULT_PLATFORMS")
  2305 		self.__baseuserdefaultplatforms = self.CheckValue(evaluator, "BASE_USER_DEFAULT_PLATFORMS")
  2364 		self.__baseuserdefaultplatforms = evaluator.CheckedGet("BASE_USER_DEFAULT_PLATFORMS")
  2306 
  2365 
  2307 		# Only read each variant.cfg once
  2366 		# Only read each variant.cfg once
  2308 		variantCfgs = {}
  2367 		variantCfgs = {}
  2309 
  2368 
  2310 		# Group the list of configurations into "build platforms".
  2369 		# Group the list of configurations into "build platforms".
  2319 		# and VARIANT_HRH values. Each "build platform" has one associated
  2378 		# and VARIANT_HRH values. Each "build platform" has one associated
  2320 		# "export platform" but several "build platforms" can be associated
  2379 		# "export platform" but several "build platforms" can be associated
  2321 		# with the same "export platform".
  2380 		# with the same "export platform".
  2322 		exports = {}
  2381 		exports = {}
  2323 
  2382 
       
  2383 		self.__Raptor.Debug("MetaReader: configsToBuild:  %s", [b.name for b in configsToBuild])
  2324 		for buildConfig in configsToBuild:
  2384 		for buildConfig in configsToBuild:
  2325 			# get everything we need to know about the configuration
  2385 			# get everything we need to know about the configuration
  2326 			evaluator = self.__Raptor.GetEvaluator(None, buildConfig)
  2386 			evaluator = self.__Raptor.GetEvaluator(None, buildConfig)
  2327 
  2387 
  2328 			detail = {}
  2388 			detail = {}
  2329 			detail['PLATFORM'] = self.CheckValue(evaluator, "TRADITIONAL_PLATFORM")
  2389 			detail['PLATFORM'] = evaluator.CheckedGet("TRADITIONAL_PLATFORM")
  2330 			epocroot = self.CheckValue(evaluator, "EPOCROOT")
  2390 			epocroot = evaluator.CheckedGet("EPOCROOT")
  2331 			detail['EPOCROOT'] = generic_path.Path(epocroot)
  2391 			detail['EPOCROOT'] = generic_path.Path(epocroot)
  2332 
  2392 
  2333 			sbs_build_dir = self.CheckValue(evaluator, "SBS_BUILD_DIR")
  2393 			sbs_build_dir = evaluator.CheckedGet("SBS_BUILD_DIR")
  2334 			detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir)
  2394 			detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir)
  2335 			flm_export_dir = self.CheckValue(evaluator, "FLM_EXPORT_DIR")
  2395 			flm_export_dir = evaluator.CheckedGet("FLM_EXPORT_DIR")
  2336 			detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir)
  2396 			detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir)
  2337 			detail['CACHEID'] = flm_export_dir
  2397 			detail['CACHEID'] = flm_export_dir
  2338 			if raptor_utilities.getOSPlatform().startswith("win"):
  2398 			if raptor_utilities.getOSPlatform().startswith("win"):
  2339 				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.WINDOWS")
  2399 				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.WINDOWS")
  2340 			else:
  2400 			else:
  2341 				detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.LINUX")
  2401 				detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.LINUX")
  2342 
  2402 
  2343 			# Apply OS variant provided we are not ignoring this
  2403 			# Apply OS variant provided we are not ignoring this
  2344 			if not self.__Raptor.ignoreOsDetection:
  2404 			if not self.__Raptor.ignoreOsDetection:
  2345 				self.__Raptor.Debug("Automatic OS detection enabled.")
  2405 				self.__Raptor.Debug("Automatic OS detection enabled.")
  2346 				self.ApplyOSVariant(buildConfig, epocroot)
  2406 				self.ApplyOSVariant(buildConfig, epocroot)
  2348 				self.__Raptor.Debug("Automatic OS detection disabled.")
  2408 				self.__Raptor.Debug("Automatic OS detection disabled.")
  2349 
  2409 
  2350 			# is this a feature variant config or an ordinary variant
  2410 			# is this a feature variant config or an ordinary variant
  2351 			fv = evaluator.Get("FEATUREVARIANTNAME")
  2411 			fv = evaluator.Get("FEATUREVARIANTNAME")
  2352 			if fv:
  2412 			if fv:
  2353 				variantHdr = self.CheckValue(evaluator, "VARIANT_HRH")
  2413 				variantHdr = evaluator.CheckedGet("VARIANT_HRH")
  2354 				variantHRH = generic_path.Path(variantHdr)
  2414 				variantHRH = generic_path.Path(variantHdr)
  2355 				detail['ISFEATUREVARIANT'] = True
  2415 				detail['ISFEATUREVARIANT'] = True
  2356 			else:
  2416 			else:
  2357 				variantCfg = self.CheckValue(evaluator, "VARIANT_CFG")
  2417 				variantCfg = evaluator.CheckedGet("VARIANT_CFG")
  2358 				variantCfg = generic_path.Path(variantCfg)
  2418 				variantCfg = generic_path.Path(variantCfg)
  2359 				if not variantCfg in variantCfgs:
  2419 				if not variantCfg in variantCfgs:
  2360 					# get VARIANT_HRH from the variant.cfg file
  2420 					# get VARIANT_HRH from the variant.cfg file
  2361 					varCfg = getVariantCfgDetail(detail['EPOCROOT'], variantCfg)
  2421 					varCfg = getVariantCfgDetail(detail['EPOCROOT'], variantCfg)
  2362 					variantCfgs[variantCfg] = varCfg['VARIANT_HRH']
  2422 					variantCfgs[variantCfg] = varCfg['VARIANT_HRH']
  2367 				variantHRH = variantCfgs[variantCfg]
  2427 				variantHRH = variantCfgs[variantCfg]
  2368 				detail['ISFEATUREVARIANT'] = False
  2428 				detail['ISFEATUREVARIANT'] = False
  2369 
  2429 
  2370 			detail['VARIANT_HRH'] = variantHRH
  2430 			detail['VARIANT_HRH'] = variantHRH
  2371 			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)
  2372 			detail['SYSTEMINCLUDE'] = self.CheckValue(evaluator, "SYSTEMINCLUDE")
  2432 			detail['SYSTEMINCLUDE'] = evaluator.CheckedGet("SYSTEMINCLUDE")
  2373 
  2433 
  2374 			detail['METADEPS'] = [] # Dependency targets for all metadata files in this platform
       
  2375 
  2434 
  2376 			# find all the interface names we need
  2435 			# find all the interface names we need
  2377 			ifaceTypes = self.CheckValue(evaluator, "INTERFACE_TYPES")
  2436 			ifaceTypes = evaluator.CheckedGet("INTERFACE_TYPES")
  2378 			interfaces = ifaceTypes.split()
  2437 			interfaces = ifaceTypes.split()
  2379 
  2438 
  2380 			for iface in interfaces:
  2439 			for iface in interfaces:
  2381 				detail[iface] = self.CheckValue(evaluator, "INTERFACE." + iface)
  2440 				detail[iface] = evaluator.CheckedGet("INTERFACE." + iface)
  2382 
  2441 
  2383 			# not test code unless positively specified
  2442 			# not test code unless positively specified
  2384 			detail['TESTCODE'] = self.CheckValue(evaluator, "TESTCODE", "")
  2443 			detail['TESTCODE'] = evaluator.CheckedGet("TESTCODE", "")
  2385 
  2444 
  2386 			# make a key that identifies this platform uniquely
  2445 			# make a key that identifies this platform uniquely
  2387 			# - used to tell us whether we have done the pre-processing
  2446 			# - used to tell us whether we have done the pre-processing
  2388 			# we need already using another platform with compatible values.
  2447 			# we need already using another platform with compatible values.
  2389 
  2448 
  2450 
  2509 
  2451 		# one platform is picked as the "default" for extracting things
  2510 		# one platform is picked as the "default" for extracting things
  2452 		# that are supposedly platform independent (e.g. PRJ_PLATFORMS)
  2511 		# that are supposedly platform independent (e.g. PRJ_PLATFORMS)
  2453 		self.defaultPlatform = self.ExportPlatforms[0]
  2512 		self.defaultPlatform = self.ExportPlatforms[0]
  2454 
  2513 
  2455 	def CheckValue(self, evaluator, key, default = None):
  2514 
  2456 		"""extract a value from an evaluator and raise an exception if None.
  2515 	def ReadBldInfFiles(self, aComponentList, doexport, dobuild = True):
  2457 
       
  2458 		An optional default can be set to replace a None value."""
       
  2459 		value = evaluator.Get(key)
       
  2460 		if value == None:
       
  2461 			if default == None:
       
  2462 				raise MetaDataError("configuration " + evaluator.config.name +
       
  2463 								    " has no variable " + key)
       
  2464 			else:
       
  2465 				return default
       
  2466 		return value
       
  2467 
       
  2468 	def ReadBldInfFiles(self, aFileList, doExportOnly):
       
  2469 		"""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.
  2470 
  2517 
  2471 		The returned specification nodes will be suitable for all the build
  2518 		The returned specification nodes will be suitable for all the build
  2472 		configurations under consideration (using Filter nodes where required).
  2519 		configurations under consideration (using Filter nodes where required).
  2473 		"""
  2520 		"""
  2474 
  2521 
  2475 		# we need a Filter node per export platform
  2522 		# we need a Filter node per export platform
  2476 		exportNodes = []
  2523 		exportNodes = []
  2477 		for i,ep in enumerate(self.ExportPlatforms):
  2524 		for i,ep in enumerate(self.ExportPlatforms):
  2478 			filter = raptor_data.Filter("export_" + str(i))
  2525 			filter = raptor_data.Filter(name = "export_" + str(i))
  2479 
  2526 
  2480 			# what configurations is this node active for?
  2527 			# what configurations is this node active for?
  2481 			for config in ep['configs']:
  2528 			for config in ep['configs']:
  2482 				filter.AddConfigCondition(config.name)
  2529 				filter.AddConfigCondition(config.name)
  2483 
  2530 
  2484 			exportNodes.append(filter)
  2531 			exportNodes.append(filter)
  2485 
  2532 
  2486 		# we need a Filter node per build platform
  2533 		# we need a Filter node per build platform
  2487 		platformNodes = []
  2534 		platformNodes = []
  2488 		for i,bp in enumerate(self.BuildPlatforms):
  2535 		for i,bp in enumerate(self.BuildPlatforms):
  2489 			filter = raptor_data.Filter("build_" + str(i))
  2536 			filter = raptor_data.Filter(name = "build_" + str(i))
  2490 
  2537 
  2491 			# what configurations is this node active for?
  2538 			# what configurations is this node active for?
  2492 			for config in bp['configs']:
  2539 			for config in bp['configs']:
  2493 				filter.AddConfigCondition(config.name)
  2540 				filter.AddConfigCondition(config.name)
  2494 
  2541 
  2500 			filter.AddVariant(platformVar)
  2547 			filter.AddVariant(platformVar)
  2501 			platformNodes.append(filter)
  2548 			platformNodes.append(filter)
  2502 
  2549 
  2503 		# 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
  2504 		# 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.
  2505 		for bif in aFileList:
  2552 		for c in aComponentList:
  2506 			if bif.isFile():
  2553 			if c.bldinf_filename.isFile():
  2507 				self.__Raptor.Info("Processing %s", str(bif))
  2554 				self.__Raptor.Info("Processing %s", str(c.bldinf_filename))
  2508 				try:
  2555 				try:
  2509 					self.AddComponentNodes(bif, exportNodes, platformNodes)
  2556 					self.AddComponentNodes(c, exportNodes, platformNodes)
  2510 
  2557 
  2511 				except MetaDataError, e:
  2558 				except MetaDataError, e:
  2512 					self.__Raptor.Error(e.Text, bldinf=str(bif))
  2559 					self.__Raptor.Error(e.Text, bldinf=str(c.bldinf_filename))
  2513 					if not self.__Raptor.keepGoing:
  2560 					if not self.__Raptor.keepGoing:
  2514 						return []
  2561 						return []
  2515 			else:
  2562 			else:
  2516 				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))
  2517 				if not self.__Raptor.keepGoing:
  2564 				if not self.__Raptor.keepGoing:
  2518 					return []
  2565 					return []
  2519 
  2566 
  2520 		# now we have the top-level structure in place...
  2567 		# now we have the top-level structure in place...
  2521 		#
  2568 		#
  2543 
  2590 
  2544 		# 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
  2545 		# before we can do anything else (because raptor itself must do
  2592 		# before we can do anything else (because raptor itself must do
  2546 		# some exports before the MMP files that include them can be
  2593 		# some exports before the MMP files that include them can be
  2547 		# processed).
  2594 		# processed).
  2548 		for i,p in enumerate(exportNodes):
  2595 		if doexport:
  2549 			exportPlatform = self.ExportPlatforms[i]
  2596 			for i,p in enumerate(exportNodes):
  2550 			for s in p.GetChildSpecs():
  2597 				exportPlatform = self.ExportPlatforms[i]
  2551 				try:
  2598 				for s in p.GetChildSpecs():
  2552 					self.ProcessExports(s, exportPlatform)
  2599 					try:
  2553 
  2600 						self.ProcessExports(s, exportPlatform)
  2554 				except MetaDataError, e:
  2601 
  2555 					self.__Raptor.Error("%s",e.Text)
  2602 					except MetaDataError, e:
  2556 					if not self.__Raptor.keepGoing:
  2603 						self.__Raptor.Error("%s",e.Text)
  2557 						return []
  2604 						if not self.__Raptor.keepGoing:
       
  2605 							return []
       
  2606 		else:
       
  2607 			self.__Raptor.Info("Not Processing Exports (--noexport enabled)")
  2558 
  2608 
  2559 		# 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
  2560 		# only option is specified in the run
  2610 		# only option is specified in the run
  2561 		if (self.__Raptor.doExportOnly):
  2611 		if dobuild is not True:
  2562 			self.__Raptor.Info("Processing Exports only")
  2612 			self.__Raptor.Info("Processing Exports only")
  2563 			return[]
  2613 			return[]
  2564 
  2614 
  2565 		# 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
  2566 		# new Interfaces which can be used for EXTENSIONS. Make sure
  2616 		# new Interfaces which can be used for EXTENSIONS. Make sure
  2599 	def ModuleName(self,aBldInfPath):
  2649 	def ModuleName(self,aBldInfPath):
  2600 		"""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"""
  2601 
  2651 
  2602 		def LeftPortionOf(pth,sep):
  2652 		def LeftPortionOf(pth,sep):
  2603 			""" 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. 
  2604 			The partition is case-insentive."""
  2654 			The split is case-insensitive."""
  2605 			length = len((pth.lower().partition(sep.lower()))[0])
  2655 			length = len((pth.lower().split(sep.lower()))[0])
  2606 			return pth[0:length]
  2656 			return pth[0:length]
  2607 			
  2657 			
  2608 		modulePath = LeftPortionOf(LeftPortionOf(os.path.dirname(aBldInfPath), "group"), "ongoing")
  2658 		modulePath = LeftPortionOf(LeftPortionOf(os.path.dirname(aBldInfPath), "group"), "ongoing")
  2609 		moduleName = os.path.basename(modulePath.strip("/"))
  2659 		moduleName = os.path.basename(modulePath.strip("/"))
  2610 		
  2660 		
  2613 		if moduleName == "" or moduleName.endswith(":"):
  2663 		if moduleName == "" or moduleName.endswith(":"):
  2614 			moduleName = "module"
  2664 			moduleName = "module"
  2615 		return moduleName
  2665 		return moduleName
  2616 
  2666 
  2617 
  2667 
  2618 	def AddComponentNodes(self, buildFile, exportNodes, platformNodes):
  2668 	def AddComponentNodes(self, component, exportNodes, platformNodes):	
  2619 		"""Add Specification nodes for a bld.inf to the appropriate platforms."""
  2669 		"""Add Specification nodes for a bld.inf to the appropriate platforms."""
  2620 		bldInfFile = BldInfFile(buildFile, self.__gnucpp, self.__Raptor)
  2670 		bldInfFile = BldInfFile(component.bldinf_filename, self.__gnucpp, component.depfiles, self.__Raptor)
  2621 
  2671 		component.bldinf = bldInfFile 
  2622 		specName = self.getSpecName(buildFile, fullPath=True)
  2672 
  2623 
  2673 		specName = getSpecName(component.bldinf_filename, fullPath=True)
  2624 		if isinstance(buildFile, raptor_xml.SystemModelComponent):
  2674 
       
  2675 		if isinstance(component.bldinf, raptor_xml.SystemModelComponent):
  2625 			# this component came from a system_definition.xml
  2676 			# this component came from a system_definition.xml
  2626 			layer = buildFile.GetContainerName("layer")
  2677 			layer = component.bldinf.GetContainerName("layer")
  2627 			component = buildFile.GetContainerName("component")
  2678 			componentName = component.bldinf.GetContainerName("component")
  2628 		else:
  2679 		else:
  2629 			# 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
  2630 			layer = ""
  2681 			layer = ""
  2631 			component = ""
  2682 			componentName = ""
  2632 
  2683 
  2633 		# exports are independent of build platform
  2684 		# exports are independent of build platform
  2634 		for i,ep in enumerate(self.ExportPlatforms):
  2685 		for i,ep in enumerate(self.ExportPlatforms):
  2635 			specNode = raptor_data.Specification(specName)
  2686 			specNode = raptor_data.Specification(name = specName)
  2636 
  2687 
  2637 			# keep the BldInfFile object for later
  2688 			# keep the BldInfFile object for later
  2638 			specNode.bldinf = bldInfFile
  2689 			specNode.component = component
  2639 
  2690 
  2640 			# add some basic data in a component-wide variant
  2691 			# add some basic data in a component-wide variant
  2641 			var = raptor_data.Variant()
  2692 			var = raptor_data.Variant(name='component-wide')
  2642 			var.AddOperation(raptor_data.Set("COMPONENT_META", str(buildFile)))
  2693 			var.AddOperation(raptor_data.Set("COMPONENT_META", str(component.bldinf_filename)))
  2643 			var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
  2694 			var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
  2644 			var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2695 			var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2645 			specNode.AddVariant(var)
  2696 			specNode.AddVariant(var)
  2646 
  2697 
  2647 			# add this bld.inf Specification to the export platform
  2698 			# add this bld.inf Specification to the export platform
  2648 			exportNodes[i].AddChild(specNode)
  2699 			exportNodes[i].AddChild(specNode)
       
  2700 			component.exportspecs.append(specNode)
  2649 
  2701 
  2650 		# get the relevant build platforms
  2702 		# get the relevant build platforms
  2651 		listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform)
  2703 		listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform)
  2652 		platforms = getBuildableBldInfBuildPlatforms(listedPlatforms,
  2704 		platforms = getBuildableBldInfBuildPlatforms(listedPlatforms,
  2653 													self.__defaultplatforms,
  2705 								self.__defaultplatforms,
  2654 													self.__basedefaultplatforms,
  2706 								self.__basedefaultplatforms,
  2655 													self.__baseuserdefaultplatforms)
  2707 								self.__baseuserdefaultplatforms)
  2656 
  2708 
  2657 
  2709 
  2658 
  2710 		outputDir = BldInfFile.outputPathFragment(component.bldinf_filename)
  2659 		outputDir = BldInfFile.outputPathFragment(buildFile)
       
  2660 
  2711 
  2661 		# Calculate "module name"
  2712 		# Calculate "module name"
  2662 		modulename = self.ModuleName(str(buildFile))
  2713 		modulename = self.ModuleName(str(component.bldinf_filename))
  2663 
  2714 
  2664 		for i,bp in enumerate(self.BuildPlatforms):
  2715 		for i,bp in enumerate(self.BuildPlatforms):
       
  2716 			plat = bp['PLATFORM']
  2665 			if bp['PLATFORM'] in platforms:
  2717 			if bp['PLATFORM'] in platforms:
  2666 				specNode = raptor_data.Specification(specName)
  2718 				specNode = raptor_data.Specification(name = specName)
  2667 
  2719 
  2668 				# keep the BldInfFile object for later
  2720 				# remember what component this spec node comes from for later
  2669 				specNode.bldinf = bldInfFile
  2721 				specNode.component = component
  2670 
  2722 
  2671 				# add some basic data in a component-wide variant
  2723 				# add some basic data in a component-wide variant
  2672 				var = raptor_data.Variant()
  2724 				var = raptor_data.Variant(name='component-wide-settings-' + plat)
  2673 				var.AddOperation(raptor_data.Set("COMPONENT_META",str(buildFile)))
  2725 				var.AddOperation(raptor_data.Set("COMPONENT_META",str(component.bldinf_filename)))
  2674 				var.AddOperation(raptor_data.Set("COMPONENT_NAME", component))
  2726 				var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName))
  2675 				var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2727 				var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer))
  2676 				var.AddOperation(raptor_data.Set("MODULE", modulename))
  2728 				var.AddOperation(raptor_data.Set("MODULE", modulename))
  2677 				var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/'))
  2729 				var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/'))
  2678 				var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/'))
  2730 				var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/'))
  2679 				var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/'))
  2731 				var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/'))
  2680 
  2732 
  2681 				var.AddOperation(raptor_data.Set("TEST_OPTION", specNode.bldinf.getRomTestType(bp)))
  2733 				var.AddOperation(raptor_data.Set("TEST_OPTION", component.bldinf.getRomTestType(bp)))
  2682 				specNode.AddVariant(var)
  2734 				specNode.AddVariant(var)
  2683 
  2735 
  2684 				# add this bld.inf Specification to the build platform
  2736 				# add this bld.inf Specification to the build platform
  2685 				platformNodes[i].AddChild(specNode)
  2737 				platformNodes[i].AddChild(specNode)
       
  2738 				# also attach it into the component
       
  2739 				component.specs.append(specNode)
  2686 
  2740 
  2687 	def ProcessExports(self, componentNode, exportPlatform):
  2741 	def ProcessExports(self, componentNode, exportPlatform):
  2688 		"""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.
  2689 
  2743 
  2690 		This will actually perform exports as certain types of files (.mmh)
  2744 		This will actually perform exports as certain types of files (.mmh)
  2692 		(and parts of other bld.inf nodes) can be processed.
  2746 		(and parts of other bld.inf nodes) can be processed.
  2693 
  2747 
  2694 		[some MMP files #include exported .mmh files]
  2748 		[some MMP files #include exported .mmh files]
  2695 		"""
  2749 		"""
  2696 		if exportPlatform["TESTCODE"]:
  2750 		if exportPlatform["TESTCODE"]:
  2697 			exports = componentNode.bldinf.getTestExports(exportPlatform)
  2751 			exports = componentNode.component.bldinf.getTestExports(exportPlatform)
  2698 		else:
  2752 		else:
  2699 			exports = componentNode.bldinf.getExports(exportPlatform)
  2753 			exports = componentNode.component.bldinf.getExports(exportPlatform)
  2700 
  2754 
  2701 		self.__Raptor.Debug("%i exports for %s",
  2755 		self.__Raptor.Debug("%i exports for %s",
  2702 							len(exports), str(componentNode.bldinf.filename))
  2756 							len(exports), str(componentNode.component.bldinf.filename))
  2703 		if exports:
  2757 		if exports:
  2704 
  2758 
  2705 			# each export is either a 'copy' or 'unzip'
  2759 			# each export is either a 'copy' or 'unzip'
  2706 			# maybe we should trap multiple exports to the same location here?
  2760 			# maybe we should trap multiple exports to the same location here?
  2707 			epocroot = str(exportPlatform["EPOCROOT"])
  2761 			epocroot = str(exportPlatform["EPOCROOT"])
  2708 			bldinf_filename = str(componentNode.bldinf.filename)
  2762 			bldinf_filename = str(componentNode.component.bldinf.filename)
  2709 			exportwhatlog="<whatlog bldinf='%s' mmp='' config=''>\n" % bldinf_filename
  2763 			exportwhatlog="<whatlog bldinf='%s' mmp='' config=''>\n" % bldinf_filename
  2710 			for export in exports:
  2764 			for export in exports:
  2711 				expSrc = export.getSource()
  2765 				expSrc = export.getSource()
  2712 				expDstList = export.getDestination() # Might not be a list in all circumstances
  2766 				expDstList = export.getDestination() # Might not be a list in all circumstances
  2713 
  2767 
  2726 					try:
  2780 					try:
  2727 						if export.getAction() == "copy":
  2781 						if export.getAction() == "copy":
  2728 							# export the file
  2782 							# export the file
  2729 							exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename)
  2783 							exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename)
  2730 						else:
  2784 						else:
  2731 							# unzip the zip
       
  2732 							exportwhatlog += ("<archive zipfile='" + str(fromFile) + "'>\n")
  2785 							exportwhatlog += ("<archive zipfile='" + str(fromFile) + "'>\n")
  2733 							members = self.UnzipExport(fromFile, toFile,
  2786 							members = self.UnzipExport(fromFile, toFile,
  2734 									str(exportPlatform['SBS_BUILD_DIR']),
  2787 									str(exportPlatform['SBS_BUILD_DIR']),
  2735 									bldinf_filename)
  2788 									bldinf_filename)
  2736 							if members != None:
  2789 							if members != None:
  2874 						if os.path.exists(expfilename):
  2927 						if os.path.exists(expfilename):
  2875 							os.chmod(expfilename,stat.S_IREAD | stat.S_IWRITE)
  2928 							os.chmod(expfilename,stat.S_IREAD | stat.S_IWRITE)
  2876 						expfile = open(expfilename, 'wb')
  2929 						expfile = open(expfilename, 'wb')
  2877 						expfile.write(exportzip.read(file))
  2930 						expfile.write(exportzip.read(file))
  2878 						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 						
  2879 						# 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
  2880 						accesstime = time.time()
  2938 						accesstime = time.time()
  2881 						datetime = exportzip.getinfo(file).date_time
  2939 						datetime = exportzip.getinfo(file).date_time
  2882 						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]), \
  2883 									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))
  2913 		"""
  2971 		"""
  2914 		if buildPlatform["ISFEATUREVARIANT"]:
  2972 		if buildPlatform["ISFEATUREVARIANT"]:
  2915 			return	# feature variation does not run extensions at all
  2973 			return	# feature variation does not run extensions at all
  2916 		
  2974 		
  2917 		if buildPlatform["TESTCODE"]:
  2975 		if buildPlatform["TESTCODE"]:
  2918 			extensions = componentNode.bldinf.getTestExtensions(buildPlatform)
  2976 			extensions = componentNode.component.bldinf.getTestExtensions(buildPlatform)
  2919 		else:
  2977 		else:
  2920 			extensions = componentNode.bldinf.getExtensions(buildPlatform)
  2978 			extensions = componentNode.component.bldinf.getExtensions(buildPlatform)
  2921 
  2979 
  2922 		self.__Raptor.Debug("%i template extension makefiles for %s",
  2980 		self.__Raptor.Debug("%i template extension makefiles for %s",
  2923 							len(extensions), str(componentNode.bldinf.filename))
  2981 							len(extensions), str(componentNode.component.bldinf.filename))
  2924 
  2982 
  2925 		for i,extension in enumerate(extensions):
  2983 		for i,extension in enumerate(extensions):
  2926 			if self.__Raptor.projects:
  2984 			if self.__Raptor.projects:
  2927 				if not extension.nametag in self.__Raptor.projects:
  2985 				if not extension.nametag in self.__Raptor.projects:
  2928 					self.__Raptor.Debug("Skipping %s", extension.getMakefile())
  2986 					self.__Raptor.Debug("Skipping %s", extension.getMakefile())
  2997 		This happens after exports have been handled.
  3055 		This happens after exports have been handled.
  2998 		"""
  3056 		"""
  2999 		gnuList = []
  3057 		gnuList = []
  3000 		makefileList = []
  3058 		makefileList = []
  3001 
  3059 
       
  3060 
       
  3061 		component = componentNode.component
       
  3062 
       
  3063 
  3002 		if buildPlatform["TESTCODE"]:
  3064 		if buildPlatform["TESTCODE"]:
  3003 			MMPList = componentNode.bldinf.getTestMMPList(buildPlatform)
  3065 			MMPList = component.bldinf.getTestMMPList(buildPlatform)
  3004 		else:
  3066 		else:
  3005 			MMPList = componentNode.bldinf.getMMPList(buildPlatform)
  3067 			MMPList = component.bldinf.getMMPList(buildPlatform)
  3006 
  3068 
  3007 		bldInfFile = componentNode.bldinf.filename
  3069 		bldInfFile = component.bldinf.filename
  3008 
  3070 
  3009 		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 
  3010 			projectname = mmpFileEntry.filename.File().lower()
  3074 			projectname = mmpFileEntry.filename.File().lower()
  3011 
  3075 
  3012 			if self.__Raptor.projects:
  3076 			if self.__Raptor.projects:
  3013 				if not projectname in self.__Raptor.projects:
  3077 				if not projectname in self.__Raptor.projects:
  3014 					self.__Raptor.Debug("Skipping %s", str(mmpFileEntry.filename))
  3078 					self.__Raptor.Debug("Skipping %s", str(mmpFileEntry.filename))
  3022 				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))
  3023 				continue
  3087 				continue
  3024 
  3088 
  3025 			mmpFile = MMPFile(foundmmpfile,
  3089 			mmpFile = MMPFile(foundmmpfile,
  3026 								   self.__gnucpp,
  3090 								   self.__gnucpp,
  3027 								   bldinf = componentNode.bldinf,
  3091 								   component.bldinf,
       
  3092 								   component.depfiles,
  3028 								   log = self.__Raptor)
  3093 								   log = self.__Raptor)
  3029 
  3094 
  3030 			mmpFilename = mmpFile.filename
  3095 			mmpFilename = mmpFile.filename
  3031 
  3096 
  3032 			self.__Raptor.Info("Processing %s for platform %s",
  3097 			self.__Raptor.Info("Processing %s for platform %s",
  3056 			# feature variation only processes FEATUREVARIANT binaries
  3121 			# feature variation only processes FEATUREVARIANT binaries
  3057 			if buildPlatform["ISFEATUREVARIANT"] and not backend.featureVariant:
  3122 			if buildPlatform["ISFEATUREVARIANT"] and not backend.featureVariant:
  3058 				continue
  3123 				continue
  3059 			
  3124 			
  3060 			# now build the specification tree
  3125 			# now build the specification tree
  3061 			mmpSpec = raptor_data.Specification(self.getSpecName(mmpFilename))
  3126 			mmpSpec = raptor_data.Specification(generic_path.Path(getSpecName(mmpFilename)))
  3062 			var = backend.BuildVariant
  3127 			var = backend.BuildVariant
  3063 
  3128 
  3064 			var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename)))
  3129 			var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename)))
  3065 
  3130 
  3066 			# 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
  3092 								    bldinf=str(bldInfFile))
  3157 								    bldinf=str(bldInfFile))
  3093 				continue
  3158 				continue
  3094 
  3159 
  3095 			# 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
  3096 			# container bld.inf exported headers
  3161 			# container bld.inf exported headers
  3097 			for export in componentNode.bldinf.getExports(buildPlatform):
  3162 			for export in componentNode.component.bldinf.getExports(buildPlatform):
  3098 				destination = export.getDestination()
  3163 				destination = export.getDestination()
  3099 				if isinstance(destination, list):
  3164 				if isinstance(destination, list):
  3100 					exportfile = str(destination[0])
  3165 					exportfile = str(destination[0])
  3101 				else:
  3166 				else:
  3102 					exportfile = str(destination)
  3167 					exportfile = str(destination)
  3105 					var.AddOperation(raptor_data.Append("EXPORTHEADERS", str(exportfile)))
  3170 					var.AddOperation(raptor_data.Append("EXPORTHEADERS", str(exportfile)))
  3106 
  3171 
  3107 			# now we have something worth adding to the component
  3172 			# now we have something worth adding to the component
  3108 			mmpSpec.AddVariant(var)
  3173 			mmpSpec.AddVariant(var)
  3109 			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))
  3110 
  3185 
  3111 			# resources, stringtables and bitmaps are sub-nodes of this project
  3186 			# resources, stringtables and bitmaps are sub-nodes of this project
  3112 			# (do not add these for feature variant builds)
  3187 			# (do not add these for feature variant builds)
  3113 			
  3188 			
  3114 			if not buildPlatform["ISFEATUREVARIANT"]:
  3189 			if not buildPlatform["ISFEATUREVARIANT"]:
  3148 					continue
  3223 					continue
  3149 				elif projectname in self.projectList:
  3224 				elif projectname in self.projectList:
  3150 					self.projectList.remove(projectname)
  3225 					self.projectList.remove(projectname)
  3151 
  3226 
  3152 			self.__Raptor.Debug("%i gnumakefile extension makefiles for %s",
  3227 			self.__Raptor.Debug("%i gnumakefile extension makefiles for %s",
  3153 						len(gnuList), str(componentNode.bldinf.filename))
  3228 						len(gnuList), str(componentNode.component.bldinf.filename))
  3154 			var = raptor_data.Variant()
  3229 			var = raptor_data.Variant()
  3155 			gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName()))
  3230 			gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName()))
  3156 			interface = buildPlatform["ext_makefile"]
  3231 			interface = buildPlatform["ext_makefile"]
  3157 			gnuSpec.SetInterface(interface)
  3232 			gnuSpec.SetInterface(interface)
  3158 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), g.getMakefileName())
  3233 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), g.getMakefileName())
  3180 					continue
  3255 					continue
  3181 				elif projectname in self.projectList:
  3256 				elif projectname in self.projectList:
  3182 					projectList.remove(projectname)
  3257 					projectList.remove(projectname)
  3183 
  3258 
  3184 			self.__Raptor.Debug("%i makefile extension makefiles for %s",
  3259 			self.__Raptor.Debug("%i makefile extension makefiles for %s",
  3185 						len(makefileList), str(componentNode.bldinf.filename))
  3260 						len(makefileList), str(componentNode.component.bldinf.filename))
  3186 			var = raptor_data.Variant()
  3261 			var = raptor_data.Variant()
  3187 			gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName()))
  3262 			gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName()))
  3188 			interface = buildPlatform["ext_makefile"]
  3263 			interface = buildPlatform["ext_makefile"]
  3189 			gnuSpec.SetInterface(interface)
  3264 			gnuSpec.SetInterface(interface)
  3190 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), m.getMakefileName())
  3265 			gnumakefilePath = raptor_utilities.resolveSymbianPath(str(bldInfFile), m.getMakefileName())
  3201 				value = value.replace('$/', '/').replace('$;', ':')
  3276 				value = value.replace('$/', '/').replace('$;', ':')
  3202 				var.AddOperation(raptor_data.Set(standardVariable, value))
  3277 				var.AddOperation(raptor_data.Set(standardVariable, value))
  3203 			gnuSpec.AddVariant(var)
  3278 			gnuSpec.AddVariant(var)
  3204 			componentNode.AddChild(gnuSpec)
  3279 			componentNode.AddChild(gnuSpec)
  3205 
  3280 
  3206 	def getSpecName(self, aFileRoot, fullPath=False):
       
  3207 		"""Returns a build spec name: this is the file root (full path
       
  3208 		or simple file name) made safe for use as a file name."""
       
  3209 
       
  3210 		if fullPath:
       
  3211 			specName = str(aFileRoot).replace("/","_")
       
  3212 			specName = specName.replace(":","")
       
  3213 		else:
       
  3214 			specName = aFileRoot.File()
       
  3215 
       
  3216 		return specName.lower()
       
  3217 
  3281 
  3218 	def ApplyOSVariant(self, aBuildUnit, aEpocroot):
  3282 	def ApplyOSVariant(self, aBuildUnit, aEpocroot):
  3219 		# Form path to kif.xml and path to buildinfo.txt
  3283 		# Form path to kif.xml and path to buildinfo.txt
  3220 		kifXmlPath = generic_path.Join(aEpocroot, "epoc32", "data","kif.xml")
  3284 		kifXmlPath = generic_path.Join(aEpocroot, "epoc32", "data","kif.xml")
  3221 		buildInfoTxtPath = generic_path.Join(aEpocroot, "epoc32", "data","buildinfo.txt")
  3285 		buildInfoTxtPath = generic_path.Join(aEpocroot, "epoc32", "data","buildinfo.txt")