Beispiel #1
0
	def exec_command(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		Logs.debug('runner: %r'%(cmd,))
		Logs.debug('runner_env: kw=%s'%kw)
		if self.logger:
			self.logger.info(cmd)
		if'stdout'not in kw:
			kw['stdout']=subprocess.PIPE
		if'stderr'not in kw:
			kw['stderr']=subprocess.PIPE
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!"%cmd[0])
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=Utils.subprocess.PIPE
			del kw['input']
		try:
			if kw['stdout']or kw['stderr']:
				p=subprocess.Popen(cmd,**kw)
				(out,err)=p.communicate(**wargs)
				ret=p.returncode
			else:
				out,err=(None,None)
				ret=subprocess.Popen(cmd,**kw).wait(**wargs)
		except Exception ,e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
Beispiel #2
0
	def cmd_and_log(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		Logs.debug('runner: %r'%(cmd,))
		if'quiet'in kw:
			quiet=kw['quiet']
			del kw['quiet']
		else:
			quiet=None
		if'output'in kw:
			to_ret=kw['output']
			del kw['output']
		else:
			to_ret=STDOUT
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!"%cmd[0])
		kw['stdout']=kw['stderr']=subprocess.PIPE
		if quiet is None:
			self.to_log(cmd)
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=Utils.subprocess.PIPE
			del kw['input']
		try:
			p=subprocess.Popen(cmd,**kw)
			(out,err)=p.communicate(**wargs)
		except Exception ,e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
Beispiel #3
0
	def exec_command(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		# FIXME: hacky solution to fix PIC-PIE-conflict
		if '-shared' in cmd:
			Logs.debug('runner: old %r'%(cmd,))
			cmd = [x for x in cmd if x != '-fPIE' and x != '-pie']
		Logs.debug('runner: %r',cmd)
		Logs.debug('runner_env: kw=%s',kw)
		if self.logger:
			self.logger.info(cmd)
		if'stdout'not in kw:
			kw['stdout']=subprocess.PIPE
		if'stderr'not in kw:
			kw['stderr']=subprocess.PIPE
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError('Program %s not found!'%cmd[0])
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=subprocess.PIPE
			del kw['input']
		if'cwd'in kw:
			if not isinstance(kw['cwd'],str):
				kw['cwd']=kw['cwd'].abspath()
		try:
			ret,out,err=Utils.run_process(cmd,kw,wargs)
		except Exception ,e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]
Beispiel #4
0
	def exec_command(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		if kw['shell']:
			Logs.debug('runner: (shell) %s'%cmd)
		else:
			Logs.debug('runner: (exec) %s'%Utils.list2cmdline(cmd))
		Logs.debug('runner_env: kw=%s'%kw)
		if self.logger:
			self.logger.info(cmd)
		if'stdout'not in kw:
			kw['stdout']=subprocess.PIPE
		if'stderr'not in kw:
			kw['stderr']=subprocess.PIPE
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!"%cmd[0])
		try:
			if kw['stdout']or kw['stderr']:
				p=subprocess.Popen(cmd,**kw)
				(out,err)=p.communicate()
				ret=p.returncode
			else:
				out,err=(None,None)
				ret=subprocess.Popen(cmd,**kw).wait()
		except Exception ,e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
Beispiel #5
0
	def exec_command(self, cmd, **kw):
		"""
		Execute a command and return the exit status. If the context has the attribute 'log',
		capture and log the process stderr/stdout for logging purposes::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		This method captures the standard/error outputs (Issue 1101), but it does not return the values
		unlike :py:meth:`waflib.Context.Context.cmd_and_log`

		:param cmd: command argument for subprocess.Popen
		:param kw: keyword arguments for subprocess.Popen
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		Logs.debug('runner: %r' % cmd)
		Logs.debug('runner_env: kw=%s' % kw)

		if self.logger:
			self.logger.info(cmd)

		if 'stdout' not in kw:
			kw['stdout'] = subprocess.PIPE
		if 'stderr' not in kw:
			kw['stderr'] = subprocess.PIPE

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!" % cmd[0])

		try:
			if kw['stdout'] or kw['stderr']:
				p = subprocess.Popen(cmd, **kw)
				(out, err) = p.communicate()
				ret = p.returncode
			else:
				out, err = (None, None)
				ret = subprocess.Popen(cmd, **kw).wait()
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if out:
			if not isinstance(out, str):
				out = out.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.debug('out: %s' % out)
			else:
				Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
		if err:
			if not isinstance(err, str):
				err = err.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.error('err: %s' % err)
			else:
				Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})

		return ret
Beispiel #6
0
 def cmd_and_log(self, cmd, **kw):
     subprocess = Utils.subprocess
     kw["shell"] = isinstance(cmd, str)
     Logs.debug("runner: %r", cmd)
     if "quiet" in kw:
         quiet = kw["quiet"]
         del kw["quiet"]
     else:
         quiet = None
     if "output" in kw:
         to_ret = kw["output"]
         del kw["output"]
     else:
         to_ret = STDOUT
     if Logs.verbose and not kw["shell"] and not Utils.check_exe(cmd[0]):
         raise Errors.WafError("Program %r not found!" % cmd[0])
     kw["stdout"] = kw["stderr"] = subprocess.PIPE
     if quiet is None:
         self.to_log(cmd)
     wargs = {}
     if "timeout" in kw:
         if kw["timeout"] is not None:
             wargs["timeout"] = kw["timeout"]
         del kw["timeout"]
     if "input" in kw:
         if kw["input"]:
             wargs["input"] = kw["input"]
             kw["stdin"] = subprocess.PIPE
         del kw["input"]
     if "cwd" in kw:
         if not isinstance(kw["cwd"], str):
             kw["cwd"] = kw["cwd"].abspath()
     try:
         ret, out, err = Utils.run_process(cmd, kw, wargs)
     except Exception as e:
         raise Errors.WafError("Execution failure: %s" % str(e), ex=e)
     if not isinstance(out, str):
         out = out.decode(sys.stdout.encoding or "iso8859-1")
     if not isinstance(err, str):
         err = err.decode(sys.stdout.encoding or "iso8859-1")
     if out and quiet != STDOUT and quiet != BOTH:
         self.to_log("out: %s" % out)
     if err and quiet != STDERR and quiet != BOTH:
         self.to_log("err: %s" % err)
     if ret:
         e = Errors.WafError("Command %r returned %r" % (cmd, ret))
         e.returncode = ret
         e.stderr = err
         e.stdout = out
         raise e
     if to_ret == BOTH:
         return (out, err)
     elif to_ret == STDERR:
         return err
     return out
Beispiel #7
0
	def cmd_and_log(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		Logs.debug('runner: %r'%(cmd,))
		if'quiet'in kw:
			quiet=kw['quiet']
			del kw['quiet']
		else:
			quiet=None
		if'output'in kw:
			to_ret=kw['output']
			del kw['output']
		else:
			to_ret=STDOUT
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!"%cmd[0])
		kw['stdout']=kw['stderr']=subprocess.PIPE
		if quiet is None:
			self.to_log(cmd)
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=subprocess.PIPE
			del kw['input']
		try:
			p=subprocess.Popen(cmd,**kw)
			(out,err)=p.communicate(**wargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
		if not isinstance(out,str):
			out=out.decode(sys.stdout.encoding or'iso8859-1')
		if not isinstance(err,str):
			err=err.decode(sys.stdout.encoding or'iso8859-1')
		if out and quiet!=STDOUT and quiet!=BOTH:
			self.to_log('out: %s'%out)
		if err and quiet!=STDERR and quiet!=BOTH:
			self.to_log('err: %s'%err)
		if p.returncode:
			e=Errors.WafError('Command %r returned %r'%(cmd,p.returncode))
			e.returncode=p.returncode
			e.stderr=err
			e.stdout=out
			raise e
		if to_ret==BOTH:
			return(out,err)
		elif to_ret==STDERR:
			return err
		return out
def find_program(self,filename,**kw):
	exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
	environ=kw.get('environ',getattr(self,'environ',os.environ))
	ret=''
	filename=Utils.to_list(filename)
	msg=kw.get('msg',', '.join(filename))
	var=kw.get('var','')
	if not var:
		var=re.sub(r'[-.]','_',filename[0].upper())
	path_list=kw.get('path_list','')
	if path_list:
		path_list=Utils.to_list(path_list)
	else:
		path_list=environ.get('PATH','').split(os.pathsep)
	if var in environ:
		filename=environ[var]
		if os.path.isfile(filename):
			ret=[filename]
		else:
			ret=self.cmd_to_list(filename)
	elif self.env[var]:
		ret=self.env[var]
		ret=self.cmd_to_list(ret)
	else:
		if not ret:
			ret=self.find_binary(filename,exts.split(','),path_list)
		if not ret and Utils.winreg:
			ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
		if not ret and Utils.winreg:
			ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
		ret=self.cmd_to_list(ret)
	if ret:
		if len(ret)==1:
			retmsg=ret[0]
		else:
			retmsg=ret
	else:
		retmsg=False
	self.msg("Checking for program '%s'"%msg,retmsg,**kw)
	if not kw.get('quiet',None):
		self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
	if not ret:
		self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename)
	interpreter=kw.get('interpreter',None)
	if interpreter is None:
		if not Utils.check_exe(ret[0],env=environ):
			self.fatal('Program %r is not executable'%ret)
		self.env[var]=ret
	else:
		self.env[var]=self.env[interpreter]+ret
	return ret
Beispiel #9
0
	def exec_command(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		Logs.debug('runner: %r'%(cmd,))
		Logs.debug('runner_env: kw=%s'%kw)
		if self.logger:
			self.logger.info(cmd)
		if'stdout'not in kw:
			kw['stdout']=subprocess.PIPE
		if'stderr'not in kw:
			kw['stderr']=subprocess.PIPE
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!"%cmd[0])
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=subprocess.PIPE
			del kw['input']
		try:
			if kw['stdout']or kw['stderr']:
				p=subprocess.Popen(cmd,**kw)
				(out,err)=p.communicate(**wargs)
				ret=p.returncode
			else:
				out,err=(None,None)
				ret=subprocess.Popen(cmd,**kw).wait(**wargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
		if out:
			if not isinstance(out,str):
				out=out.decode(sys.stdout.encoding or'iso8859-1')
			if self.logger:
				self.logger.debug('out: %s'%out)
			else:
				Logs.info(out,extra={'stream':sys.stdout,'c1':''})
		if err:
			if not isinstance(err,str):
				err=err.decode(sys.stdout.encoding or'iso8859-1')
			if self.logger:
				self.logger.error('err: %s'%err)
			else:
				Logs.info(err,extra={'stream':sys.stderr,'c1':''})
		return ret
Beispiel #10
0
 def exec_command(self, cmd, **kw):
     subprocess = Utils.subprocess
     kw["shell"] = isinstance(cmd, str)
     Logs.debug("runner: %r", cmd)
     Logs.debug("runner_env: kw=%s", kw)
     if self.logger:
         self.logger.info(cmd)
     if "stdout" not in kw:
         kw["stdout"] = subprocess.PIPE
     if "stderr" not in kw:
         kw["stderr"] = subprocess.PIPE
     if Logs.verbose and not kw["shell"] and not Utils.check_exe(cmd[0]):
         raise Errors.WafError("Program %s not found!" % cmd[0])
     wargs = {}
     if "timeout" in kw:
         if kw["timeout"] is not None:
             wargs["timeout"] = kw["timeout"]
         del kw["timeout"]
     if "input" in kw:
         if kw["input"]:
             wargs["input"] = kw["input"]
             kw["stdin"] = subprocess.PIPE
         del kw["input"]
     if "cwd" in kw:
         if not isinstance(kw["cwd"], str):
             kw["cwd"] = kw["cwd"].abspath()
     try:
         ret, out, err = Utils.run_process(cmd, kw, wargs)
     except Exception as e:
         raise Errors.WafError("Execution failure: %s" % str(e), ex=e)
     if out:
         if not isinstance(out, str):
             out = out.decode(sys.stdout.encoding or "iso8859-1")
         if self.logger:
             self.logger.debug("out: %s", out)
         else:
             Logs.info(out, extra={"stream": sys.stdout, "c1": ""})
     if err:
         if not isinstance(err, str):
             err = err.decode(sys.stdout.encoding or "iso8859-1")
         if self.logger:
             self.logger.error("err: %s" % err)
         else:
             Logs.info(err, extra={"stream": sys.stderr, "c1": ""})
     return ret
Beispiel #11
0
	def cmd_and_log(self,cmd,**kw):
		subprocess=Utils.subprocess
		kw['shell']=isinstance(cmd,str)
		Logs.debug('runner: %r',cmd)
		if'quiet'in kw:
			quiet=kw['quiet']
			del kw['quiet']
		else:
			quiet=None
		if'output'in kw:
			to_ret=kw['output']
			del kw['output']
		else:
			to_ret=STDOUT
		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
			raise Errors.WafError('Program %r not found!'%cmd[0])
		kw['stdout']=kw['stderr']=subprocess.PIPE
		if quiet is None:
			self.to_log(cmd)
		wargs={}
		if'timeout'in kw:
			if kw['timeout']is not None:
				wargs['timeout']=kw['timeout']
			del kw['timeout']
		if'input'in kw:
			if kw['input']:
				wargs['input']=kw['input']
				kw['stdin']=subprocess.PIPE
			del kw['input']
		if'cwd'in kw:
			if not isinstance(kw['cwd'],str):
				kw['cwd']=kw['cwd'].abspath()
		try:
			ret,out,err=Utils.run_process(cmd,kw,wargs)
		except Exception ,e:
			raise Errors.WafError('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]
Beispiel #12
0
	def cmd_and_log(self, cmd, **kw):
		"""
		Executes a process and returns stdout/stderr if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object (configuration tests)::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Errors.WafError as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:type cmd: list or string
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: a tuple containing the contents of stdout and stderr
		:rtype: string
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		self.log_command(cmd, kw)

		quiet = kw.pop('quiet', None)
		to_ret = kw.pop('output', STDOUT)

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError('Program %r not found!' % cmd[0])

		kw['stdout'] = kw['stderr'] = subprocess.PIPE
		if quiet is None:
			self.to_log(cmd)

		cargs = {}
		if 'timeout' in kw:
			if sys.hexversion >= 0x3030000:
				cargs['timeout'] = kw['timeout']
				if not 'start_new_session' in kw:
					kw['start_new_session'] = True
			del kw['timeout']
		if 'input' in kw:
			if kw['input']:
				cargs['input'] = kw['input']
				kw['stdin'] = subprocess.PIPE
			del kw['input']

		if 'cwd' in kw:
			if not isinstance(kw['cwd'], str):
				kw['cwd'] = kw['cwd'].abspath()

		encoding = kw.pop('decode_as', default_encoding)

		try:
			ret, out, err = Utils.run_process(cmd, kw, cargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if not isinstance(out, str):
			out = out.decode(encoding, errors='replace')
		if not isinstance(err, str):
			err = err.decode(encoding, errors='replace')

		if out and quiet != STDOUT and quiet != BOTH:
			self.to_log('out: %s' % out)
		if err and quiet != STDERR and quiet != BOTH:
			self.to_log('err: %s' % err)

		if ret:
			e = Errors.WafError('Command %r returned %r' % (cmd, ret))
			e.returncode = ret
			e.stderr = err
			e.stdout = out
			raise e

		if to_ret == BOTH:
			return (out, err)
		elif to_ret == STDERR:
			return err
		return out
Beispiel #13
0
	def exec_command(self, cmd, **kw):
		"""
		Runs an external process and returns the exit status::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
		stdout/stderr values captured.

		:param cmd: command argument for subprocess.Popen
		:type cmd: string or list
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		self.log_command(cmd, kw)

		if self.logger:
			self.logger.info(cmd)

		if 'stdout' not in kw:
			kw['stdout'] = subprocess.PIPE
		if 'stderr' not in kw:
			kw['stderr'] = subprocess.PIPE

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError('Program %s not found!' % cmd[0])

		cargs = {}
		if 'timeout' in kw:
			if sys.hexversion >= 0x3030000:
				cargs['timeout'] = kw['timeout']
				if not 'start_new_session' in kw:
					kw['start_new_session'] = True
			del kw['timeout']
		if 'input' in kw:
			if kw['input']:
				cargs['input'] = kw['input']
				kw['stdin'] = subprocess.PIPE
			del kw['input']

		if 'cwd' in kw:
			if not isinstance(kw['cwd'], str):
				kw['cwd'] = kw['cwd'].abspath()

		encoding = kw.pop('decode_as', default_encoding)

		try:
			ret, out, err = Utils.run_process(cmd, kw, cargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if out:
			if not isinstance(out, str):
				out = out.decode(encoding, errors='replace')
			if self.logger:
				self.logger.debug('out: %s', out)
			else:
				Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
		if err:
			if not isinstance(err, str):
				err = err.decode(encoding, errors='replace')
			if self.logger:
				self.logger.error('err: %s' % err)
			else:
				Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})

		return ret
Beispiel #14
0
	def exec_command(self, cmd, **kw):
		"""
		Runs an external process and returns the exit status::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
		stdout/stderr values captured.

		:param cmd: command argument for subprocess.Popen
		:type cmd: string or list
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		Logs.debug('runner: %r', cmd)
		Logs.debug('runner_env: kw=%s', kw)

		if self.logger:
			self.logger.info(cmd)

		if 'stdout' not in kw:
			kw['stdout'] = subprocess.PIPE
		if 'stderr' not in kw:
			kw['stderr'] = subprocess.PIPE

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError('Program %s not found!' % cmd[0])

		wargs = {}
		if 'timeout' in kw:
			if kw['timeout'] is not None:
				wargs['timeout'] = kw['timeout']
			del kw['timeout']
		if 'input' in kw:
			if kw['input']:
				wargs['input'] = kw['input']
				kw['stdin'] = subprocess.PIPE
			del kw['input']

		if 'cwd' in kw:
			if not isinstance(kw['cwd'], str):
				kw['cwd'] = kw['cwd'].abspath()

		try:
			ret, out, err = Utils.run_process(cmd, kw, wargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if out:
			if not isinstance(out, str):
				out = out.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.debug('out: %s', out)
			else:
				Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
		if err:
			if not isinstance(err, str):
				err = err.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.error('err: %s' % err)
			else:
				Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})

		return ret
Beispiel #15
0
	def exec_command(self, cmd, **kw):
		"""
		Execute a command and return the exit status. If the context has the attribute 'log',
		capture and log the process stderr/stdout for logging purposes::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		This method captures the standard/error outputs (Issue 1101), but it does not return the values
		unlike :py:meth:`waflib.Context.Context.cmd_and_log`

		:param cmd: command argument for subprocess.Popen
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		Logs.debug('runner: %r' % (cmd,))
		Logs.debug('runner_env: kw=%s' % kw)

		if self.logger:
			self.logger.info(cmd)

		if 'stdout' not in kw:
			kw['stdout'] = subprocess.PIPE
		if 'stderr' not in kw:
			kw['stderr'] = subprocess.PIPE

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!" % cmd[0])

		wargs = {}
		if 'timeout' in kw:
			if kw['timeout'] is not None:
				wargs['timeout'] = kw['timeout']
			del kw['timeout']
		if 'input' in kw:
			if kw['input']:
				wargs['input'] = kw['input']
				kw['stdin'] = Utils.subprocess.PIPE
			del kw['input']

		try:
			if kw['stdout'] or kw['stderr']:
				p = subprocess.Popen(cmd, **kw)
				(out, err) = p.communicate(**wargs)
				ret = p.returncode
			else:
				out, err = (None, None)
				ret = subprocess.Popen(cmd, **kw).wait(**wargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if out:
			if not isinstance(out, str):
				out = out.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.debug('out: %s' % out)
			else:
				Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
		if err:
			if not isinstance(err, str):
				err = err.decode(sys.stdout.encoding or 'iso8859-1')
			if self.logger:
				self.logger.error('err: %s' % err)
			else:
				Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})

		return ret
Beispiel #16
0
def find_program(self, filename, **kw):
	"""
	Search for a program on the operating system

	When var is used, you may set os.environ[var] to help find a specific program version, for example::

		$ CC='ccache gcc' waf configure

	:param path_list: paths to use for searching
	:type param_list: list of string
	:param var: store the result to conf.env[var], by default use filename.upper()
	:type var: string
	:param ext: list of extensions for the binary (do not add an extension for portability)
	:type ext: list of string
	:param msg: name to display in the log, by default filename is used
	:type msg: string
	:param interpreter: interpreter for the program
	:type interpreter: ConfigSet variable key
	"""

	exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py')

	environ = kw.get('environ', getattr(self, 'environ', os.environ))

	ret = ''

	filename = Utils.to_list(filename)
	msg = kw.get('msg', ', '.join(filename))

	var = kw.get('var', '')
	if not var:
		var = re.sub(r'[-.]', '_', filename[0].upper())

	path_list = kw.get('path_list', '')
	if path_list:
		path_list = Utils.to_list(path_list)
	else:
		path_list = environ.get('PATH', '').split(os.pathsep)

	if var in environ:
		filename = environ[var]
		if os.path.isfile(filename):
			# typical CC=/usr/bin/gcc waf configure build
			ret = [filename]
		else:
			# case  CC='ccache gcc' waf configure build
			ret = self.cmd_to_list(filename)
	elif self.env[var]:
		# set by the user in the wscript file
		ret = self.env[var]
		ret = self.cmd_to_list(ret)
	else:
		if not ret:
			ret = self.find_binary(filename, exts.split(','), path_list)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
		ret = self.cmd_to_list(ret)


	if ret:
		if len(ret) == 1:
			retmsg = ret[0]
		else:
			retmsg = ret
	else:
		retmsg = False

	self.msg("Checking for program '%s'" % msg, retmsg, **kw)
	if not kw.get('quiet', None):
		self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret))

	if not ret:
		self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename)

	interpreter = kw.get('interpreter', None)
	if interpreter is None:
		if not Utils.check_exe(ret[0], env=environ):
			self.fatal('Program %r is not executable' % ret)
		self.env[var] = ret
	else:
		self.env[var] = self.env[interpreter] + ret

	return ret
Beispiel #17
0
    def cmd_and_log(self, cmd, **kw):
        """
		Executes a process and returns stdout/stderr if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object (configuration tests)::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Errors.WafError as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:type cmd: list or string
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: a tuple containing the contents of stdout and stderr
		:rtype: string
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object
		"""
        subprocess = Utils.subprocess
        kw['shell'] = isinstance(cmd, str)
        self.log_command(cmd, kw)

        quiet = kw.pop('quiet', None)
        to_ret = kw.pop('output', STDOUT)

        if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError('Program %r not found!' % cmd[0])

        kw['stdout'] = kw['stderr'] = subprocess.PIPE
        if quiet is None:
            self.to_log(cmd)

        cargs = {}
        if 'timeout' in kw:
            if sys.hexversion >= 0x3030000:
                cargs['timeout'] = kw['timeout']
                if not 'start_new_session' in kw:
                    kw['start_new_session'] = True
            del kw['timeout']
        if 'input' in kw:
            if kw['input']:
                cargs['input'] = kw['input']
                kw['stdin'] = subprocess.PIPE
            del kw['input']

        if 'cwd' in kw:
            if not isinstance(kw['cwd'], str):
                kw['cwd'] = kw['cwd'].abspath()

        encoding = kw.pop('decode_as', default_encoding)

        try:
            ret, out, err = Utils.run_process(cmd, kw, cargs)
        except Exception as e:
            raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

        if not isinstance(out, str):
            out = out.decode(encoding, errors='replace')
        if not isinstance(err, str):
            err = err.decode(encoding, errors='replace')

        if out and quiet != STDOUT and quiet != BOTH:
            self.to_log('out: %s' % out)
        if err and quiet != STDERR and quiet != BOTH:
            self.to_log('err: %s' % err)

        if ret:
            e = Errors.WafError('Command %r returned %r' % (cmd, ret))
            e.returncode = ret
            e.stderr = err
            e.stdout = out
            raise e

        if to_ret == BOTH:
            return (out, err)
        elif to_ret == STDERR:
            return err
        return out
Beispiel #18
0
	def cmd_and_log(self, cmd, **kw):
		"""
		Execute a command and return stdout/stderr if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Exception as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		"""
		subprocess = Utils.subprocess
		kw['shell'] = isinstance(cmd, str)
		Logs.debug('runner: %r' % (cmd,))

		if 'quiet' in kw:
			quiet = kw['quiet']
			del kw['quiet']
		else:
			quiet = None

		if 'output' in kw:
			to_ret = kw['output']
			del kw['output']
		else:
			to_ret = STDOUT

		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
			raise Errors.WafError("Program %s not found!" % cmd[0])

		kw['stdout'] = kw['stderr'] = subprocess.PIPE
		if quiet is None:
			self.to_log(cmd)

		wargs = {}
		if 'timeout' in kw:
			if kw['timeout'] is not None:
				wargs['timeout'] = kw['timeout']
			del kw['timeout']
		if 'input' in kw:
			if kw['input']:
				wargs['input'] = kw['input']
				kw['stdin'] = Utils.subprocess.PIPE
			del kw['input']

		try:
			p = subprocess.Popen(cmd, **kw)
			(out, err) = p.communicate(**wargs)
		except Exception as e:
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

		if not isinstance(out, str):
			out = out.decode(sys.stdout.encoding or 'iso8859-1')
		if not isinstance(err, str):
			err = err.decode(sys.stdout.encoding or 'iso8859-1')

		if out and quiet != STDOUT and quiet != BOTH:
			self.to_log('out: %s' % out)
		if err and quiet != STDERR and quiet != BOTH:
			self.to_log('err: %s' % err)

		if p.returncode:
			e = Errors.WafError('Command %r returned %r' % (cmd, p.returncode))
			e.returncode = p.returncode
			e.stderr = err
			e.stdout = out
			raise e

		if to_ret == BOTH:
			return (out, err)
		elif to_ret == STDERR:
			return err
		return out
Beispiel #19
0
def find_program(self, filename, **kw):
    """
	Search for a program on the operating system

	When var is used, you may set os.environ[var] to help find a specific program version, for example::

		$ CC='ccache gcc' waf configure

	:param path_list: paths to use for searching
	:type param_list: list of string
	:param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings
	:type var: string
	:param value: obtain the program from the value passed exclusively
	:type value: list or string (list is preferred)
	:param exts: list of extensions for the binary (do not add an extension for portability)
	:type exts: list of string
	:param msg: name to display in the log, by default filename is used
	:type msg: string
	:param interpreter: interpreter for the program
	:type interpreter: ConfigSet variable key
	:raises: :py:class:`waflib.Errors.ConfigurationError`
	"""

    exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd'
                  or ',.sh,.pl,.py')

    environ = kw.get('environ', getattr(self, 'environ', os.environ))

    ret = ''

    filename = Utils.to_list(filename)
    msg = kw.get('msg', ', '.join(filename))

    var = kw.get('var', '')
    if not var:
        var = re.sub(r'[-.]', '_', filename[0].upper())

    path_list = kw.get('path_list', '')
    if path_list:
        path_list = Utils.to_list(path_list)
    else:
        path_list = environ.get('PATH', '').split(os.pathsep)

    if kw.get('value'):
        # user-provided in command-line options and passed to find_program
        ret = self.cmd_to_list(kw['value'])
    elif environ.get(var):
        # user-provided in the os environment
        ret = self.cmd_to_list(environ[var])
    elif self.env[var]:
        # a default option in the wscript file
        ret = self.cmd_to_list(self.env[var])
    else:
        if not ret:
            ret = self.find_binary(filename, exts.split(','), path_list)
        if not ret and Utils.winreg:
            ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,
                                              filename)
        if not ret and Utils.winreg:
            ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,
                                              filename)
        ret = self.cmd_to_list(ret)

    if ret:
        if len(ret) == 1:
            retmsg = ret[0]
        else:
            retmsg = ret
    else:
        retmsg = False

    self.msg('Checking for program %r' % msg, retmsg, **kw)
    if not kw.get('quiet'):
        self.to_log('find program=%r paths=%r var=%r -> %r' %
                    (filename, path_list, var, ret))

    if not ret:
        self.fatal(
            kw.get('errmsg', '') or 'Could not find the program %r' % filename)

    interpreter = kw.get('interpreter')
    if interpreter is None:
        if not Utils.check_exe(ret[0], env=environ):
            self.fatal('Program %r is not executable' % ret)
        self.env[var] = ret
    else:
        self.env[var] = self.env[interpreter] + ret

    return ret
Beispiel #20
0
def find_program(self, filename, **kw):
	"""
	Search for a program on the operating system

	When var is used, you may set os.environ[var] to help find a specific program version, for example::

		$ CC='ccache gcc' waf configure

	:param path_list: paths to use for searching
	:type param_list: list of string
	:param var: store the result to conf.env[var], by default use filename.upper()
	:type var: string
	:param ext: list of extensions for the binary (do not add an extension for portability)
	:type ext: list of string
	:param msg: name to display in the log, by default filename is used
	:type msg: string
	:param interpreter: interpreter for the program
	:type interpreter: ConfigSet variable key
	"""

	exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py')

	environ = kw.get('environ', getattr(self, 'environ', os.environ))

	ret = ''

	filename = Utils.to_list(filename)
	msg = kw.get('msg', ', '.join(filename))

	var = kw.get('var', '')
	if not var:
		var = re.sub(r'[-.]', '_', filename[0].upper())

	path_list = kw.get('path_list', '')
	if path_list:
		path_list = Utils.to_list(path_list)
	else:
		path_list = environ.get('PATH', '').split(os.pathsep)

	if var in environ:
		filename = environ[var]
		if os.path.isfile(filename):
			# typical CC=/usr/bin/gcc waf configure build
			ret = [filename]
		else:
			# case  CC='ccache gcc' waf configure build
			ret = self.cmd_to_list(filename)
	elif self.env[var]:
		# set by the user in the wscript file
		ret = self.env[var]
		ret = self.cmd_to_list(ret)
	else:
		if not ret:
			ret = self.find_binary(filename, exts.split(','), path_list)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
		ret = self.cmd_to_list(ret)


	if ret:
		if len(ret) == 1:
			retmsg = ret[0]
		else:
			retmsg = ret
	else:
		retmsg = False

	self.msg("Checking for program '%s'" % msg, retmsg, **kw)
	if not kw.get('quiet', None):
		self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret))

	if not ret:
		self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename)

	interpreter = kw.get('interpreter', None)
	if interpreter is None:
		if not Utils.check_exe(ret[0], env=environ):
			self.fatal('Program %r is not executable' % ret)
		self.env[var] = ret
	else:
		self.env[var] = self.env[interpreter] + ret

	return ret
Beispiel #21
0
def find_program(self, filename, **kw):
	"""
	Search for a program on the operating system

	When var is used, you may set os.environ[var] to help find a specific program version, for example::

		$ CC='ccache gcc' waf configure

	:param path_list: paths to use for searching
	:type param_list: list of string
	:param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings
	:type var: string
	:param value: obtain the program from the value passed exclusively
	:type value: list or string (list is preferred)
	:param ext: list of extensions for the binary (do not add an extension for portability)
	:type ext: list of string
	:param msg: name to display in the log, by default filename is used
	:type msg: string
	:param interpreter: interpreter for the program
	:type interpreter: ConfigSet variable key
	"""

	exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py')

	environ = kw.get('environ', getattr(self, 'environ', os.environ))

	ret = ''

	filename = Utils.to_list(filename)
	msg = kw.get('msg', ', '.join(filename))

	var = kw.get('var', '')
	if not var:
		var = re.sub(r'[-.]', '_', filename[0].upper())

	path_list = kw.get('path_list', '')
	if path_list:
		path_list = Utils.to_list(path_list)
	else:
		path_list = environ.get('PATH', '').split(os.pathsep)

	if kw.get('value'):
		# user-provided in command-line options and passed to find_program
		ret = self.cmd_to_list(kw['value'])
	elif var in environ:
		# user-provided in the os environment
		ret = self.cmd_to_list(environ[var])
	elif self.env[var]:
		# a default option in the wscript file
		ret = self.cmd_to_list(self.env[var])
	else:
		if not ret:
			ret = self.find_binary(filename, exts.split(','), path_list)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
		if not ret and Utils.winreg:
			ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
		ret = self.cmd_to_list(ret)

	if ret:
		if len(ret) == 1:
			retmsg = ret[0]
		else:
			retmsg = ret
	else:
		retmsg = False

	self.msg('Checking for program %r' % msg, retmsg, **kw)
	if not kw.get('quiet'):
		self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret))

	if not ret:
		self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename)

	interpreter = kw.get('interpreter')
	if interpreter is None:
		if not Utils.check_exe(ret[0], env=environ):
			self.fatal('Program %r is not executable' % ret)
		self.env[var] = ret
	else:
		self.env[var] = self.env[interpreter] + ret

	return ret
Beispiel #22
0
    def cmd_and_log(self, cmd, **kw):
        """
		Execute a command and return stdout if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Exception as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:param kw: keyword arguments for subprocess.Popen
		"""
        subprocess = Utils.subprocess
        kw['shell'] = isinstance(cmd, str)
        Logs.debug('runner: %r' % cmd)

        if 'quiet' in kw:
            quiet = kw['quiet']
            del kw['quiet']
        else:
            quiet = None

        if 'output' in kw:
            to_ret = kw['output']
            del kw['output']
        else:
            to_ret = STDOUT

        if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError("Program %s not found!" % cmd[0])

        kw['stdout'] = kw['stderr'] = subprocess.PIPE
        if quiet is None:
            self.to_log(cmd)
        try:
            p = subprocess.Popen(cmd, **kw)
            (out, err) = p.communicate()
        except Exception as e:
            raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

        if not isinstance(out, str):
            out = out.decode(sys.stdout.encoding or 'iso8859-1')
        if not isinstance(err, str):
            err = err.decode(sys.stdout.encoding or 'iso8859-1')

        if out and quiet != STDOUT and quiet != BOTH:
            self.to_log('out: %s' % out)
        if err and quiet != STDERR and quiet != BOTH:
            self.to_log('err: %s' % err)

        if p.returncode:
            e = Errors.WafError('Command %r returned %r' % (cmd, p.returncode))
            e.returncode = p.returncode
            e.stderr = err
            e.stdout = out
            raise e

        if to_ret == BOTH:
            return (out, err)
        elif to_ret == STDERR:
            return err
        return out
Beispiel #23
0
def find_program(self, filename, **kw):
    """
    Search for a program on the operating system

    When var is used, you may set os.environ[var] to help find a specific program version, for example::

            $ CC='ccache gcc' waf configure

    :param path_list: paths to use for searching
    :type param_list: list of string
    :param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings
    :type var: string
    :param value: obtain the program from the value passed exclusively
    :type value: list or string (list is preferred)
    :param exts: list of extensions for the binary (do not add an extension for portability)
    :type exts: list of string
    :param msg: name to display in the log, by default filename is used
    :type msg: string
    :param interpreter: interpreter for the program
    :type interpreter: ConfigSet variable key
    :raises: :py:class:`waflib.Errors.ConfigurationError`
    """

    exts = kw.get("exts", Utils.is_win32 and ".exe,.com,.bat,.cmd" or ",.sh,.pl,.py")

    environ = kw.get("environ", getattr(self, "environ", os.environ))

    ret = ""

    filename = Utils.to_list(filename)
    msg = kw.get("msg", ", ".join(filename))

    var = kw.get("var", "")
    if not var:
        var = re.sub(r"[-.]", "_", filename[0].upper())

    path_list = kw.get("path_list", "")
    if path_list:
        path_list = Utils.to_list(path_list)
    else:
        path_list = environ.get("PATH", "").split(os.pathsep)

    if kw.get("value"):
        # user-provided in command-line options and passed to find_program
        ret = self.cmd_to_list(kw["value"])
    elif environ.get(var):
        # user-provided in the os environment
        ret = self.cmd_to_list(environ[var])
    elif self.env[var]:
        # a default option in the wscript file
        ret = self.cmd_to_list(self.env[var])
    else:
        if not ret:
            ret = self.find_binary(filename, exts.split(","), path_list)
        if not ret and Utils.winreg:
            ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
        if not ret and Utils.winreg:
            ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
        ret = self.cmd_to_list(ret)

    if ret:
        if len(ret) == 1:
            retmsg = ret[0]
        else:
            retmsg = ret
    else:
        retmsg = False

    self.msg("Checking for program %r" % msg, retmsg, **kw)
    if not kw.get("quiet"):
        self.to_log(
            f"find program={filename!r} paths={path_list!r} var={var!r} -> {ret!r}"
        )

    if not ret:
        self.fatal(kw.get("errmsg", "") or "Could not find the program %r" % filename)

    interpreter = kw.get("interpreter")
    if interpreter is None:
        if not Utils.check_exe(ret[0], env=environ):
            self.fatal("Program %r is not executable" % ret)
        self.env[var] = ret
    else:
        self.env[var] = self.env[interpreter] + ret

    return ret
Beispiel #24
0
    def exec_command(self, cmd, **kw):
        """
		Runs an external process and returns the exit status::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
		stdout/stderr values captured.

		:param cmd: command argument for subprocess.Popen
		:type cmd: string or list
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		"""
        subprocess = Utils.subprocess
        kw["shell"] = isinstance(cmd, str)
        Logs.debug("runner: %r", cmd)
        Logs.debug("runner_env: kw=%s", kw)

        if self.logger:
            self.logger.info(cmd)

        if "stdout" not in kw:
            kw["stdout"] = subprocess.PIPE
        if "stderr" not in kw:
            kw["stderr"] = subprocess.PIPE

        if Logs.verbose and not kw["shell"] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError("Program %s not found!" % cmd[0])

        cargs = {}
        if "timeout" in kw:
            if kw["timeout"] is not None:
                if kw["shell"]:
                    Logs.warn("Shell commands cannot timeout %r", cmd)
            del kw["timeout"]
        if "input" in kw:
            if kw["input"]:
                cargs["input"] = kw["input"]
                kw["stdin"] = subprocess.PIPE
            del kw["input"]

        if "cwd" in kw:
            if not isinstance(kw["cwd"], str):
                kw["cwd"] = kw["cwd"].abspath()

        try:
            ret, out, err = Utils.run_process(cmd, kw, cargs)
        except Exception as e:
            raise Errors.WafError("Execution failure: %s" % str(e), ex=e)

        if out:
            if not isinstance(out, str):
                out = out.decode(sys.stdout.encoding or "iso8859-1")
            if self.logger:
                self.logger.debug("out: %s", out)
            else:
                Logs.info(out, extra={"stream": sys.stdout, "c1": ""})
        if err:
            if not isinstance(err, str):
                err = err.decode(sys.stdout.encoding or "iso8859-1")
            if self.logger:
                self.logger.error("err: %s" % err)
            else:
                Logs.info(err, extra={"stream": sys.stderr, "c1": ""})

        return ret
Beispiel #25
0
def exec_command(self, cmd, **kw):
    subprocess = Utils.subprocess
    kw['shell'] = isinstance(cmd, str)

    if isinstance(cmd, str):
        kw['shell'] = True
        txt = cmd
    else:
        txt = ' '.join(repr(x) if ' ' in x else x for x in cmd)

    Logs.debug('runner: %s', txt)
    Logs.debug('runner_env: kw=%s', kw)

    if self.logger:
        self.logger.info(cmd)

    if 'stdout' not in kw:
        kw['stdout'] = subprocess.PIPE
    if 'stderr' not in kw:
        kw['stderr'] = subprocess.PIPE

    if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
        raise Errors.WafError("Program %s not found!" % cmd[0])

    wargs = {}
    if 'timeout' in kw:
        if kw['timeout'] is not None:
            wargs['timeout'] = kw['timeout']
        del kw['timeout']
    if 'input' in kw:
        if kw['input']:
            wargs['input'] = kw['input']
            kw['stdin'] = Utils.subprocess.PIPE
        del kw['input']

    if 'cwd' in kw:
        if not isinstance(kw['cwd'], str):
            kw['cwd'] = kw['cwd'].abspath()

    try:
        if kw['stdout'] or kw['stderr']:
            p = subprocess.Popen(cmd, **kw)
            (out, err) = p.communicate(**wargs)
            ret = p.returncode
        else:
            out, err = (None, None)
            ret = subprocess.Popen(cmd, **kw).wait(**wargs)
    except Exception as e:
        raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

    if out:
        if not isinstance(out, str):
            out = out.decode(sys.stdout.encoding or 'iso8859-1')
        if self.logger:
            self.logger.debug('out: %s' % out)
        else:
            Logs.info(out, extra={'stream': sys.stdout, 'c1': ''})
    if err:
        if not isinstance(err, str):
            err = err.decode(sys.stdout.encoding or 'iso8859-1')
        if self.logger:
            self.logger.error('err: %s' % err)
        else:
            Logs.info(err, extra={'stream': sys.stderr, 'c1': ''})

    return ret
Beispiel #26
0
    def cmd_and_log(self, cmd, **kw):
        """
		Executes a proces and returns stdout/stderr if the execution is successful.
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
		will be bound to the WafError object::

			def configure(conf):
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
				(out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT)
				try:
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
				except Exception as e:
					print(e.stdout, e.stderr)

		:param cmd: args for subprocess.Popen
		:type cmd: list or string
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object
		"""
        subprocess = Utils.subprocess
        kw["shell"] = isinstance(cmd, str)
        Logs.debug("runner: %r", cmd)

        if "quiet" in kw:
            quiet = kw["quiet"]
            del kw["quiet"]
        else:
            quiet = None

        if "output" in kw:
            to_ret = kw["output"]
            del kw["output"]
        else:
            to_ret = STDOUT

        if Logs.verbose and not kw["shell"] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError("Program %r not found!" % cmd[0])

        kw["stdout"] = kw["stderr"] = subprocess.PIPE
        if quiet is None:
            self.to_log(cmd)

        cargs = {}
        if "timeout" in kw:
            if kw["timeout"] is not None:
                if kw["shell"]:
                    Logs.warn("Shell commands cannot timeout %r", cmd)
            del kw["timeout"]
        if "input" in kw:
            if kw["input"]:
                cargs["input"] = kw["input"]
                kw["stdin"] = subprocess.PIPE
            del kw["input"]

        if "cwd" in kw:
            if not isinstance(kw["cwd"], str):
                kw["cwd"] = kw["cwd"].abspath()

        try:
            ret, out, err = Utils.run_process(cmd, kw, cargs)
        except Exception as e:
            raise Errors.WafError("Execution failure: %s" % str(e), ex=e)

        if not isinstance(out, str):
            out = out.decode(sys.stdout.encoding or "iso8859-1")
        if not isinstance(err, str):
            err = err.decode(sys.stdout.encoding or "iso8859-1")

        if out and quiet != STDOUT and quiet != BOTH:
            self.to_log("out: %s" % out)
        if err and quiet != STDERR and quiet != BOTH:
            self.to_log("err: %s" % err)

        if ret:
            e = Errors.WafError("Command %r returned %r" % (cmd, ret))
            e.returncode = ret
            e.stderr = err
            e.stdout = out
            raise e

        if to_ret == BOTH:
            return (out, err)
        elif to_ret == STDERR:
            return err
        return out
Beispiel #27
0
    def exec_command(self, cmd, **kw):
        """
		Execute a command and return the exit status. If the context has the attribute 'log',
		capture and log the process stderr/stdout for logging purposes::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		This method captures the standard/error outputs (Issue 1101), but it does not return the values
		unlike :py:meth:`waflib.Context.Context.cmd_and_log`

		:param cmd: command argument for subprocess.Popen
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		"""
        subprocess = Utils.subprocess
        kw["shell"] = isinstance(cmd, str)
        Logs.debug("runner: %r" % (cmd,))
        Logs.debug("runner_env: kw=%s" % kw)

        if self.logger:
            self.logger.info(cmd)

        if "stdout" not in kw:
            kw["stdout"] = subprocess.PIPE
        if "stderr" not in kw:
            kw["stderr"] = subprocess.PIPE

        if Logs.verbose and not kw["shell"] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError("Program %s not found!" % cmd[0])

        wargs = {}
        if "timeout" in kw:
            if kw["timeout"] is not None:
                wargs["timeout"] = kw["timeout"]
            del kw["timeout"]
        if "input" in kw:
            if kw["input"]:
                wargs["input"] = kw["input"]
                kw["stdin"] = Utils.subprocess.PIPE
            del kw["input"]

        try:
            if kw["stdout"] or kw["stderr"]:
                p = subprocess.Popen(cmd, **kw)
                (out, err) = p.communicate(**wargs)
                ret = p.returncode
            else:
                out, err = (None, None)
                ret = subprocess.Popen(cmd, **kw).wait(**wargs)
        except Exception as e:
            raise Errors.WafError("Execution failure: %s" % str(e), ex=e)

        if out:
            if not isinstance(out, str):
                out = out.decode(sys.stdout.encoding or "iso8859-1")
            if self.logger:
                self.logger.debug("out: %s" % out)
            else:
                Logs.info(out, extra={"stream": sys.stdout, "c1": ""})
        if err:
            if not isinstance(err, str):
                err = err.decode(sys.stdout.encoding or "iso8859-1")
            if self.logger:
                self.logger.error("err: %s" % err)
            else:
                Logs.info(err, extra={"stream": sys.stderr, "c1": ""})

        return ret
Beispiel #28
0
    def exec_command(self, cmd, **kw):
        """
		Runs an external process and returns the exit status::

			def run(tsk):
				ret = tsk.generator.bld.exec_command('touch foo.txt')
				return ret

		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
		stdout/stderr values captured.

		:param cmd: command argument for subprocess.Popen
		:type cmd: string or list
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
		:type kw: dict
		:returns: process exit status
		:rtype: integer
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure
		"""
        subprocess = Utils.subprocess
        kw['shell'] = isinstance(cmd, str)
        self.log_command(cmd, kw)

        if self.logger:
            self.logger.info(cmd)

        if 'stdout' not in kw:
            kw['stdout'] = subprocess.PIPE
        if 'stderr' not in kw:
            kw['stderr'] = subprocess.PIPE

        if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
            raise Errors.WafError('Program %s not found!' % cmd[0])

        cargs = {}
        if 'timeout' in kw:
            if sys.hexversion >= 0x3030000:
                cargs['timeout'] = kw['timeout']
                if not 'start_new_session' in kw:
                    kw['start_new_session'] = True
            del kw['timeout']
        if 'input' in kw:
            if kw['input']:
                cargs['input'] = kw['input']
                kw['stdin'] = subprocess.PIPE
            del kw['input']

        if 'cwd' in kw:
            if not isinstance(kw['cwd'], str):
                kw['cwd'] = kw['cwd'].abspath()

        encoding = kw.pop('decode_as', default_encoding)

        try:
            ret, out, err = Utils.run_process(cmd, kw, cargs)
        except Exception as e:
            raise Errors.WafError('Execution failure: %s' % str(e), ex=e)

        if out:
            if not isinstance(out, str):
                out = out.decode(encoding, errors='replace')
            if self.logger:
                self.logger.debug('out: %s', out)
            else:
                Logs.info(out, extra={'stream': sys.stdout, 'c1': ''})
        if err:
            if not isinstance(err, str):
                err = err.decode(encoding, errors='replace')
            if self.logger:
                self.logger.error('err: %s' % err)
            else:
                Logs.info(err, extra={'stream': sys.stderr, 'c1': ''})

        return ret