sbsv2/raptor/python/raptor_make.py
branchfix
changeset 357 b4baa7ca35a7
parent 355 24d0baf736db
child 360 77642c41e033
equal deleted inserted replaced
356:245e5b9fda51 357:b4baa7ca35a7
    34 
    34 
    35 
    35 
    36 class BadMakeEngineException(Exception):
    36 class BadMakeEngineException(Exception):
    37 	pass
    37 	pass
    38 
    38 
       
    39 def XMLEscapeLog(stream):
       
    40 	inRecipe = False
       
    41 
       
    42 	for line in stream:
       
    43 		if line.startswith("<recipe"):
       
    44 			inRecipe = True
       
    45 		elif line.startswith("</recipe"):
       
    46 			inRecipe = False
       
    47 			
       
    48 		# unless we are inside a "recipe", any line not starting
       
    49 		# with "<" is free text that must be escaped.
       
    50 		if inRecipe or line.startswith("<"):
       
    51 			yield line
       
    52 		else:
       
    53 			yield escape(line)
       
    54 
       
    55 def AnnoFileParseOutput(annofile):
       
    56 	af = open(annofile, "r")
       
    57 
       
    58 	inOutput = False
       
    59 	inParseJob = False
       
    60 	for line in af:
       
    61 		line = line.rstrip("\n\r")
       
    62 
       
    63 		if not inOutput:
       
    64 			if line.startswith("<output>"):
       
    65 				inOutput = True	
       
    66 				yield unescape(line[8:])+'\n'
       
    67 				# This is make output so don't unescape it.
       
    68 			elif line.startswith('<output src="prog">'):
       
    69 				line = line[19:]
       
    70 				inOutput = True	
       
    71 				yield unescape(line)+'\n'
       
    72 		else:
       
    73 			end_output = line.find("</output>")
       
    74 		
       
    75 			if end_output != -1:
       
    76 				line = line[:end_output]
       
    77 				inOutput = False
       
    78 			
       
    79 			yield unescape(line)+'\n'
       
    80 
       
    81 	af.close()
       
    82 
       
    83 
       
    84 
    39 # raptor_make module classes
    85 # raptor_make module classes
    40 
    86 
    41 class MakeEngine(object):
    87 class MakeEngine(object):
    42 
    88 
    43 	def __init__(self, Raptor, engine="make_engine"):
    89 	def __init__(self, Raptor, engine="make_engine"):
    79 			# options
   125 			# options
    80 			self.makefileOption = evaluator.Get("makefile")
   126 			self.makefileOption = evaluator.Get("makefile")
    81 			self.keepGoingOption = evaluator.Get("keep_going")
   127 			self.keepGoingOption = evaluator.Get("keep_going")
    82 			self.jobsOption = evaluator.Get("jobs")
   128 			self.jobsOption = evaluator.Get("jobs")
    83 			self.defaultMakeOptions = evaluator.Get("defaultoptions")
   129 			self.defaultMakeOptions = evaluator.Get("defaultoptions")
       
   130 
       
   131 			# Logging
       
   132 			#  copylogfromannofile means, for emake, that we should ignore 
       
   133 			# emake's console output and instead extract output from its annotation
       
   134 			# file.  This is a workaround for a problem where some emake
       
   135 			# console output is lost.  The annotation file has a copy of this
       
   136 			# output in the "parse" job and it turns out to be uncorrupted.
       
   137 			self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true")
       
   138 			self.annoFileName = None
       
   139 
       
   140 			if self.copyLogFromAnnoFile:
       
   141 				for o in self.raptor.makeOptions:
       
   142 					if o.startswith("--mo=--emake-annofile="):
       
   143 						self.annoFileName = o[22:]
       
   144 
       
   145 				if not self.annoFileName:
       
   146 					self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>")
       
   147 					self.copyLogFromAnnoFile = False
    84 
   148 
    85 			# buffering
   149 			# buffering
    86 			self.scrambled = (evaluator.Get("scrambled") == "true")
   150 			self.scrambled = (evaluator.Get("scrambled") == "true")
    87 
   151 
    88 			# check tool versions
   152 			# check tool versions
   479 			# clock skew messages from some build engines scatter their
   543 			# clock skew messages from some build engines scatter their
   480 			# output across our xml.
   544 			# output across our xml.
   481 			stderrfilename = makefile+'.stderr'
   545 			stderrfilename = makefile+'.stderr'
   482 			stdoutfilename = makefile+'.stdout'
   546 			stdoutfilename = makefile+'.stdout'
   483 			command += " 2>'%s' " % stderrfilename
   547 			command += " 2>'%s' " % stderrfilename
   484 			command += " >'%s' " % stdoutfilename
   548 
       
   549 			# Keep a copy of the stdout too in the case of using the 
       
   550 			# annofile - so that we can trap the problem that
       
   551 			# makes the copy-log-from-annofile workaround necessary
       
   552 			# and perhaps determine when we can remove it.
       
   553 			if self.copyLogFromAnnoFile:
       
   554 				command += " >'%s' " % stdoutfilename
   485 
   555 
   486 			# Substitute the makefile name for any occurrence of #MAKEFILE#
   556 			# Substitute the makefile name for any occurrence of #MAKEFILE#
   487 			command = command.replace("#MAKEFILE#", str(makefile))
   557 			command = command.replace("#MAKEFILE#", str(makefile))
   488 
   558 
   489 			self.raptor.Info("Executing '%s'", command)
   559 			self.raptor.Info("Executing '%s'", command)
   517 						stderr=subprocess.STDOUT,
   587 						stderr=subprocess.STDOUT,
   518 						shell = False,
   588 						shell = False,
   519 						universal_newlines=True, env=makeenv)
   589 						universal_newlines=True, env=makeenv)
   520 				stream = p.stdout
   590 				stream = p.stdout
   521 
   591 
   522 				line = " "
   592 				inRecipe = False
   523 				while line:
   593 
   524 					line = stream.readline()
   594 				if not self.copyLogFromAnnoFile:
   525 
   595 					for l in XMLEscapeLog(stream):
   526 				# should be done now
   596 						self.raptor.out.write(l)
   527 				returncode = p.wait()
   597 
   528 
   598 					returncode = p.wait()
   529 				# Report end-time of the build
   599 				else:
   530 				self.raptor.InfoEndTime(object_type = "makefile",
   600 					returncode = p.wait()
   531 						task = "build", key = str(makefile))
   601 
   532 
   602 					annofilename = self.annoFileName.replace("#MAKEFILE#",makefile)
   533 				try:
   603 					try:
   534 					e = open(stdoutfilename,"r")
   604 						for l in XMLEscapeLog(AnnoFileParseOutput(annofilename)):
   535 					inRecipe = False
   605 							self.raptor.out.write(l)
   536 					for line in e:
   606 					except Exception,e:
   537 						if line.startswith("<recipe"):
   607 						self.raptor.Error("Couldn't complete stdout output from annofile %s for %s - '%s'", annofile, command, str(e))
   538 							inRecipe = True
       
   539 						elif line.startswith("</recipe"):
       
   540 							inRecipe = False
       
   541 						
       
   542 						# unless we are inside a "recipe", any line not starting
       
   543 						# with "<" is free text that must be escaped.
       
   544 						if inRecipe or line.startswith("<"):
       
   545 							self.raptor.out.write(line)
       
   546 						else:
       
   547 							self.raptor.out.write(escape(line))
       
   548 					e.close()
       
   549 				except Exception,e:
       
   550 					self.raptor.Error("Couldn't complete stdout output for %s - '%s'", command, str(e))
       
   551 
       
   552 				if returncode != 0  and not self.raptor.keepGoing:
       
   553 					self.Tidy()
       
   554 					return False
       
   555 
   608 
   556 
   609 
   557 				# Take all the stderr output that went into the .stderr file
   610 				# Take all the stderr output that went into the .stderr file
   558 				# and put it back into the log, but safely so it can't mess up
   611 				# and put it back into the log, but safely so it can't mess up
   559 				# xml parsers.
   612 				# xml parsers.
   562 					for line in e:
   615 					for line in e:
   563 						self.raptor.out.write(escape(line))
   616 						self.raptor.out.write(escape(line))
   564 					e.close()
   617 					e.close()
   565 				except Exception,e:
   618 				except Exception,e:
   566 					self.raptor.Error("Couldn't complete stderr output for %s - '%s'", command, str(e))
   619 					self.raptor.Error("Couldn't complete stderr output for %s - '%s'", command, str(e))
       
   620 				# Report end-time of the build
       
   621 				self.raptor.InfoEndTime(object_type = "makefile",
       
   622 						task = "build", key = str(makefile))
   567 
   623 
   568 				if returncode != 0  and not self.raptor.keepGoing:
   624 				if returncode != 0  and not self.raptor.keepGoing:
   569 					self.Tidy()
   625 					self.Tidy()
   570 					return False
   626 					return False
   571 
   627 
   678 			if os.system(command) != 0:
   734 			if os.system(command) != 0:
   679 				self.raptor.Error("Failed in %s", command)
   735 				self.raptor.Error("Failed in %s", command)
   680 				return False
   736 				return False
   681 		return True
   737 		return True
   682 
   738 
       
   739 
       
   740 
   683 # raptor_make module functions
   741 # raptor_make module functions
   684 
   742 
   685 
   743 
   686 # end of the raptor_make module
   744 # end of the raptor_make module