Blame third_party/waf/waflib/Context.py

Packit Service fa3ceb
#!/usr/bin/env python
Packit Service fa3ceb
# encoding: utf-8
Packit Service fa3ceb
# Thomas Nagy, 2010-2018 (ita)
Packit Service fa3ceb
Packit Service fa3ceb
"""
Packit Service fa3ceb
Classes and functions enabling the command system
Packit Service fa3ceb
"""
Packit Service fa3ceb
Packit Service fa3ceb
import os, re, imp, sys
Packit Service fa3ceb
from waflib import Utils, Errors, Logs
Packit Service fa3ceb
import waflib.Node
Packit Service fa3ceb
Packit Service fa3ceb
# the following 3 constants are updated on each new release (do not touch)
Packit Service fa3ceb
HEXVERSION=0x2001200
Packit Service fa3ceb
"""Constant updated on new releases"""
Packit Service fa3ceb
Packit Service fa3ceb
WAFVERSION="2.0.18"
Packit Service fa3ceb
"""Constant updated on new releases"""
Packit Service fa3ceb
Packit Service fa3ceb
WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad"
Packit Service fa3ceb
"""Git revision when the waf version is updated"""
Packit Service fa3ceb
Packit Service fa3ceb
ABI = 20
Packit Service fa3ceb
"""Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)"""
Packit Service fa3ceb
Packit Service fa3ceb
DBFILE = '.wafpickle-%s-%d-%d' % (sys.platform, sys.hexversion, ABI)
Packit Service fa3ceb
"""Name of the pickle file for storing the build data"""
Packit Service fa3ceb
Packit Service fa3ceb
APPNAME = 'APPNAME'
Packit Service fa3ceb
"""Default application name (used by ``waf dist``)"""
Packit Service fa3ceb
Packit Service fa3ceb
VERSION = 'VERSION'
Packit Service fa3ceb
"""Default application version (used by ``waf dist``)"""
Packit Service fa3ceb
Packit Service fa3ceb
TOP  = 'top'
Packit Service fa3ceb
"""The variable name for the top-level directory in wscript files"""
Packit Service fa3ceb
Packit Service fa3ceb
OUT  = 'out'
Packit Service fa3ceb
"""The variable name for the output directory in wscript files"""
Packit Service fa3ceb
Packit Service fa3ceb
WSCRIPT_FILE = 'wscript'
Packit Service fa3ceb
"""Name of the waf script files"""
Packit Service fa3ceb
Packit Service fa3ceb
launch_dir = ''
Packit Service fa3ceb
"""Directory from which waf has been called"""
Packit Service fa3ceb
run_dir = ''
Packit Service fa3ceb
"""Location of the wscript file to use as the entry point"""
Packit Service fa3ceb
top_dir = ''
Packit Service fa3ceb
"""Location of the project directory (top), if the project was configured"""
Packit Service fa3ceb
out_dir = ''
Packit Service fa3ceb
"""Location of the build directory (out), if the project was configured"""
Packit Service fa3ceb
waf_dir = ''
Packit Service fa3ceb
"""Directory containing the waf modules"""
Packit Service fa3ceb
Packit Service fa3ceb
default_encoding = Utils.console_encoding()
Packit Service fa3ceb
"""Encoding to use when reading outputs from other processes"""
Packit Service fa3ceb
Packit Service fa3ceb
g_module = None
Packit Service fa3ceb
"""
Packit Service fa3ceb
Module representing the top-level wscript file (see :py:const:`waflib.Context.run_dir`)
Packit Service fa3ceb
"""
Packit Service fa3ceb
Packit Service fa3ceb
STDOUT = 1
Packit Service fa3ceb
STDERR = -1
Packit Service fa3ceb
BOTH   = 0
Packit Service fa3ceb
Packit Service fa3ceb
classes = []
Packit Service fa3ceb
"""
Packit Service fa3ceb
List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes
Packit Service fa3ceb
are added automatically by a metaclass.
Packit Service fa3ceb
"""
Packit Service fa3ceb
Packit Service fa3ceb
def create_context(cmd_name, *k, **kw):
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Returns a new :py:class:`waflib.Context.Context` instance corresponding to the given command.
Packit Service fa3ceb
	Used in particular by :py:func:`waflib.Scripting.run_command`
Packit Service fa3ceb
Packit Service fa3ceb
	:param cmd_name: command name
Packit Service fa3ceb
	:type cmd_name: string
Packit Service fa3ceb
	:param k: arguments to give to the context class initializer
Packit Service fa3ceb
	:type k: list
Packit Service fa3ceb
	:param k: keyword arguments to give to the context class initializer
Packit Service fa3ceb
	:type k: dict
Packit Service fa3ceb
	:return: Context object
Packit Service fa3ceb
	:rtype: :py:class:`waflib.Context.Context`
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	for x in classes:
Packit Service fa3ceb
		if x.cmd == cmd_name:
Packit Service fa3ceb
			return x(*k, **kw)
Packit Service fa3ceb
	ctx = Context(*k, **kw)
Packit Service fa3ceb
	ctx.fun = cmd_name
Packit Service fa3ceb
	return ctx
Packit Service fa3ceb
Packit Service fa3ceb
class store_context(type):
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Metaclass that registers command classes into the list :py:const:`waflib.Context.classes`
Packit Service fa3ceb
	Context classes must provide an attribute 'cmd' representing the command name, and a function
Packit Service fa3ceb
	attribute 'fun' representing the function name that the command uses.
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	def __init__(cls, name, bases, dct):
Packit Service fa3ceb
		super(store_context, cls).__init__(name, bases, dct)
Packit Service fa3ceb
		name = cls.__name__
Packit Service fa3ceb
Packit Service fa3ceb
		if name in ('ctx', 'Context'):
Packit Service fa3ceb
			return
Packit Service fa3ceb
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			cls.cmd
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			raise Errors.WafError('Missing command for the context class %r (cmd)' % name)
Packit Service fa3ceb
Packit Service fa3ceb
		if not getattr(cls, 'fun', None):
Packit Service fa3ceb
			cls.fun = cls.cmd
Packit Service fa3ceb
Packit Service fa3ceb
		classes.insert(0, cls)
Packit Service fa3ceb
Packit Service fa3ceb
ctx = store_context('ctx', (object,), {})
Packit Service fa3ceb
"""Base class for all :py:class:`waflib.Context.Context` classes"""
Packit Service fa3ceb
Packit Service fa3ceb
class Context(ctx):
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Default context for waf commands, and base class for new command contexts.
Packit Service fa3ceb
Packit Service fa3ceb
	Context objects are passed to top-level functions::
Packit Service fa3ceb
Packit Service fa3ceb
		def foo(ctx):
Packit Service fa3ceb
			print(ctx.__class__.__name__) # waflib.Context.Context
Packit Service fa3ceb
Packit Service fa3ceb
	Subclasses must define the class attributes 'cmd' and 'fun':
Packit Service fa3ceb
Packit Service fa3ceb
	:param cmd: command to execute as in ``waf cmd``
Packit Service fa3ceb
	:type cmd: string
Packit Service fa3ceb
	:param fun: function name to execute when the command is called
Packit Service fa3ceb
	:type fun: string
Packit Service fa3ceb
Packit Service fa3ceb
	.. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext
Packit Service fa3ceb
Packit Service fa3ceb
	"""
Packit Service fa3ceb
Packit Service fa3ceb
	errors = Errors
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Shortcut to :py:mod:`waflib.Errors` provided for convenience
Packit Service fa3ceb
	"""
Packit Service fa3ceb
Packit Service fa3ceb
	tools = {}
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	A module cache for wscript files; see :py:meth:`Context.Context.load`
Packit Service fa3ceb
	"""
Packit Service fa3ceb
Packit Service fa3ceb
	def __init__(self, **kw):
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			rd = kw['run_dir']
Packit Service fa3ceb
		except KeyError:
Packit Service fa3ceb
			rd = run_dir
Packit Service fa3ceb
Packit Service fa3ceb
		# binds the context to the nodes in use to avoid a context singleton
Packit Service fa3ceb
		self.node_class = type('Nod3', (waflib.Node.Node,), {})
Packit Service fa3ceb
		self.node_class.__module__ = 'waflib.Node'
Packit Service fa3ceb
		self.node_class.ctx = self
Packit Service fa3ceb
Packit Service fa3ceb
		self.root = self.node_class('', None)
Packit Service fa3ceb
		self.cur_script = None
Packit Service fa3ceb
		self.path = self.root.find_dir(rd)
Packit Service fa3ceb
Packit Service fa3ceb
		self.stack_path = []
Packit Service fa3ceb
		self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self}
Packit Service fa3ceb
		self.logger = None
Packit Service fa3ceb
Packit Service fa3ceb
	def finalize(self):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Called to free resources such as logger files
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			logger = self.logger
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			pass
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			Logs.free_logger(logger)
Packit Service fa3ceb
			delattr(self, 'logger')
Packit Service fa3ceb
Packit Service fa3ceb
	def load(self, tool_list, *k, **kw):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Loads a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun`
Packit Service fa3ceb
		from it.  A ``tooldir`` argument may be provided as a list of module paths.
Packit Service fa3ceb
Packit Service fa3ceb
		:param tool_list: list of Waf tool names to load
Packit Service fa3ceb
		:type tool_list: list of string or space-separated string
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		tools = Utils.to_list(tool_list)
Packit Service fa3ceb
		path = Utils.to_list(kw.get('tooldir', ''))
Packit Service fa3ceb
		with_sys_path = kw.get('with_sys_path', True)
Packit Service fa3ceb
Packit Service fa3ceb
		for t in tools:
Packit Service fa3ceb
			module = load_tool(t, path, with_sys_path=with_sys_path)
Packit Service fa3ceb
			fun = getattr(module, kw.get('name', self.fun), None)
Packit Service fa3ceb
			if fun:
Packit Service fa3ceb
				fun(self)
Packit Service fa3ceb
Packit Service fa3ceb
	def execute(self):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Here, it calls the function name in the top-level wscript file. Most subclasses
Packit Service fa3ceb
		redefine this method to provide additional functionality.
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		self.recurse([os.path.dirname(g_module.root_path)])
Packit Service fa3ceb
Packit Service fa3ceb
	def pre_recurse(self, node):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`.
Packit Service fa3ceb
		The current script is bound as a Node object on ``self.cur_script``, and the current path
Packit Service fa3ceb
		is bound to ``self.path``
Packit Service fa3ceb
Packit Service fa3ceb
		:param node: script
Packit Service fa3ceb
		:type node: :py:class:`waflib.Node.Node`
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		self.stack_path.append(self.cur_script)
Packit Service fa3ceb
Packit Service fa3ceb
		self.cur_script = node
Packit Service fa3ceb
		self.path = node.parent
Packit Service fa3ceb
Packit Service fa3ceb
	def post_recurse(self, node):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Restores ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates.
Packit Service fa3ceb
Packit Service fa3ceb
		:param node: script
Packit Service fa3ceb
		:type node: :py:class:`waflib.Node.Node`
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		self.cur_script = self.stack_path.pop()
Packit Service fa3ceb
		if self.cur_script:
Packit Service fa3ceb
			self.path = self.cur_script.parent
Packit Service fa3ceb
Packit Service fa3ceb
	def recurse(self, dirs, name=None, mandatory=True, once=True, encoding=None):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Runs user-provided functions from the supplied list of directories.
Packit Service fa3ceb
		The directories can be either absolute, or relative to the directory
Packit Service fa3ceb
		of the wscript file
Packit Service fa3ceb
Packit Service fa3ceb
		The methods :py:meth:`waflib.Context.Context.pre_recurse` and
Packit Service fa3ceb
		:py:meth:`waflib.Context.Context.post_recurse` are called immediately before
Packit Service fa3ceb
		and after a script has been executed.
Packit Service fa3ceb
Packit Service fa3ceb
		:param dirs: List of directories to visit
Packit Service fa3ceb
		:type dirs: list of string or space-separated string
Packit Service fa3ceb
		:param name: Name of function to invoke from the wscript
Packit Service fa3ceb
		:type  name: string
Packit Service fa3ceb
		:param mandatory: whether sub wscript files are required to exist
Packit Service fa3ceb
		:type  mandatory: bool
Packit Service fa3ceb
		:param once: read the script file once for a particular context
Packit Service fa3ceb
		:type once: bool
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			cache = self.recurse_cache
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			cache = self.recurse_cache = {}
Packit Service fa3ceb
Packit Service fa3ceb
		for d in Utils.to_list(dirs):
Packit Service fa3ceb
Packit Service fa3ceb
			if not os.path.isabs(d):
Packit Service fa3ceb
				# absolute paths only
Packit Service fa3ceb
				d = os.path.join(self.path.abspath(), d)
Packit Service fa3ceb
Packit Service fa3ceb
			WSCRIPT     = os.path.join(d, WSCRIPT_FILE)
Packit Service fa3ceb
			WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun)
Packit Service fa3ceb
Packit Service fa3ceb
			node = self.root.find_node(WSCRIPT_FUN)
Packit Service fa3ceb
			if node and (not once or node not in cache):
Packit Service fa3ceb
				cache[node] = True
Packit Service fa3ceb
				self.pre_recurse(node)
Packit Service fa3ceb
				try:
Packit Service fa3ceb
					function_code = node.read('r', encoding)
Packit Service fa3ceb
					exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict)
Packit Service fa3ceb
				finally:
Packit Service fa3ceb
					self.post_recurse(node)
Packit Service fa3ceb
			elif not node:
Packit Service fa3ceb
				node = self.root.find_node(WSCRIPT)
Packit Service fa3ceb
				tup = (node, name or self.fun)
Packit Service fa3ceb
				if node and (not once or tup not in cache):
Packit Service fa3ceb
					cache[tup] = True
Packit Service fa3ceb
					self.pre_recurse(node)
Packit Service fa3ceb
					try:
Packit Service fa3ceb
						wscript_module = load_module(node.abspath(), encoding=encoding)
Packit Service fa3ceb
						user_function = getattr(wscript_module, (name or self.fun), None)
Packit Service fa3ceb
						if not user_function:
Packit Service fa3ceb
							if not mandatory:
Packit Service fa3ceb
								continue
Packit Service fa3ceb
							raise Errors.WafError('No function %r defined in %s' % (name or self.fun, node.abspath()))
Packit Service fa3ceb
						user_function(self)
Packit Service fa3ceb
					finally:
Packit Service fa3ceb
						self.post_recurse(node)
Packit Service fa3ceb
				elif not node:
Packit Service fa3ceb
					if not mandatory:
Packit Service fa3ceb
						continue
Packit Service fa3ceb
					try:
Packit Service fa3ceb
						os.listdir(d)
Packit Service fa3ceb
					except OSError:
Packit Service fa3ceb
						raise Errors.WafError('Cannot read the folder %r' % d)
Packit Service fa3ceb
					raise Errors.WafError('No wscript file in directory %s' % d)
Packit Service fa3ceb
Packit Service fa3ceb
	def log_command(self, cmd, kw):
Packit Service fa3ceb
		if Logs.verbose:
Packit Service fa3ceb
			fmt = os.environ.get('WAF_CMD_FORMAT')
Packit Service fa3ceb
			if fmt == 'string':
Packit Service fa3ceb
				if not isinstance(cmd, str):
Packit Service fa3ceb
					cmd = Utils.shell_escape(cmd)
Packit Service fa3ceb
			Logs.debug('runner: %r', cmd)
Packit Service fa3ceb
			Logs.debug('runner_env: kw=%s', kw)
Packit Service fa3ceb
Packit Service fa3ceb
	def exec_command(self, cmd, **kw):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Runs an external process and returns the exit status::
Packit Service fa3ceb
Packit Service fa3ceb
			def run(tsk):
Packit Service fa3ceb
				ret = tsk.generator.bld.exec_command('touch foo.txt')
Packit Service fa3ceb
				return ret
Packit Service fa3ceb
Packit Service fa3ceb
		If the context has the attribute 'log', then captures and logs the process stderr/stdout.
Packit Service fa3ceb
		Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the
Packit Service fa3ceb
		stdout/stderr values captured.
Packit Service fa3ceb
Packit Service fa3ceb
		:param cmd: command argument for subprocess.Popen
Packit Service fa3ceb
		:type cmd: string or list
Packit Service fa3ceb
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
Packit Service fa3ceb
		:type kw: dict
Packit Service fa3ceb
		:returns: process exit status
Packit Service fa3ceb
		:rtype: integer
Packit Service fa3ceb
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
Packit Service fa3ceb
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		subprocess = Utils.subprocess
Packit Service fa3ceb
		kw['shell'] = isinstance(cmd, str)
Packit Service fa3ceb
		self.log_command(cmd, kw)
Packit Service fa3ceb
Packit Service fa3ceb
		if self.logger:
Packit Service fa3ceb
			self.logger.info(cmd)
Packit Service fa3ceb
Packit Service fa3ceb
		if 'stdout' not in kw:
Packit Service fa3ceb
			kw['stdout'] = subprocess.PIPE
Packit Service fa3ceb
		if 'stderr' not in kw:
Packit Service fa3ceb
			kw['stderr'] = subprocess.PIPE
Packit Service fa3ceb
Packit Service fa3ceb
		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
Packit Service fa3ceb
			raise Errors.WafError('Program %s not found!' % cmd[0])
Packit Service fa3ceb
Packit Service fa3ceb
		cargs = {}
Packit Service fa3ceb
		if 'timeout' in kw:
Packit Service fa3ceb
			if sys.hexversion >= 0x3030000:
Packit Service fa3ceb
				cargs['timeout'] = kw['timeout']
Packit Service fa3ceb
				if not 'start_new_session' in kw:
Packit Service fa3ceb
					kw['start_new_session'] = True
Packit Service fa3ceb
			del kw['timeout']
Packit Service fa3ceb
		if 'input' in kw:
Packit Service fa3ceb
			if kw['input']:
Packit Service fa3ceb
				cargs['input'] = kw['input']
Packit Service fa3ceb
				kw['stdin'] = subprocess.PIPE
Packit Service fa3ceb
			del kw['input']
Packit Service fa3ceb
Packit Service fa3ceb
		if 'cwd' in kw:
Packit Service fa3ceb
			if not isinstance(kw['cwd'], str):
Packit Service fa3ceb
				kw['cwd'] = kw['cwd'].abspath()
Packit Service fa3ceb
Packit Service fa3ceb
		encoding = kw.pop('decode_as', default_encoding)
Packit Service fa3ceb
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			ret, out, err = Utils.run_process(cmd, kw, cargs)
Packit Service fa3ceb
		except Exception as e:
Packit Service fa3ceb
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)
Packit Service fa3ceb
Packit Service fa3ceb
		if out:
Packit Service fa3ceb
			if not isinstance(out, str):
Packit Service fa3ceb
				out = out.decode(encoding, errors='replace')
Packit Service fa3ceb
			if self.logger:
Packit Service fa3ceb
				self.logger.debug('out: %s', out)
Packit Service fa3ceb
			else:
Packit Service fa3ceb
				Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
Packit Service fa3ceb
		if err:
Packit Service fa3ceb
			if not isinstance(err, str):
Packit Service fa3ceb
				err = err.decode(encoding, errors='replace')
Packit Service fa3ceb
			if self.logger:
Packit Service fa3ceb
				self.logger.error('err: %s' % err)
Packit Service fa3ceb
			else:
Packit Service fa3ceb
				Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})
Packit Service fa3ceb
Packit Service fa3ceb
		return ret
Packit Service fa3ceb
Packit Service fa3ceb
	def cmd_and_log(self, cmd, **kw):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Executes a process and returns stdout/stderr if the execution is successful.
Packit Service fa3ceb
		An exception is thrown when the exit status is non-0. In that case, both stderr and stdout
Packit Service fa3ceb
		will be bound to the WafError object (configuration tests)::
Packit Service fa3ceb
Packit Service fa3ceb
			def configure(conf):
Packit Service fa3ceb
				out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH)
Packit Service fa3ceb
				(out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH)
Packit Service fa3ceb
				(out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT)
Packit Service fa3ceb
				try:
Packit Service fa3ceb
					conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH)
Packit Service fa3ceb
				except Errors.WafError as e:
Packit Service fa3ceb
					print(e.stdout, e.stderr)
Packit Service fa3ceb
Packit Service fa3ceb
		:param cmd: args for subprocess.Popen
Packit Service fa3ceb
		:type cmd: list or string
Packit Service fa3ceb
		:param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate.
Packit Service fa3ceb
		:type kw: dict
Packit Service fa3ceb
		:returns: a tuple containing the contents of stdout and stderr
Packit Service fa3ceb
		:rtype: string
Packit Service fa3ceb
		:raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process
Packit Service fa3ceb
		:raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		subprocess = Utils.subprocess
Packit Service fa3ceb
		kw['shell'] = isinstance(cmd, str)
Packit Service fa3ceb
		self.log_command(cmd, kw)
Packit Service fa3ceb
Packit Service fa3ceb
		quiet = kw.pop('quiet', None)
Packit Service fa3ceb
		to_ret = kw.pop('output', STDOUT)
Packit Service fa3ceb
Packit Service fa3ceb
		if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
Packit Service fa3ceb
			raise Errors.WafError('Program %r not found!' % cmd[0])
Packit Service fa3ceb
Packit Service fa3ceb
		kw['stdout'] = kw['stderr'] = subprocess.PIPE
Packit Service fa3ceb
		if quiet is None:
Packit Service fa3ceb
			self.to_log(cmd)
Packit Service fa3ceb
Packit Service fa3ceb
		cargs = {}
Packit Service fa3ceb
		if 'timeout' in kw:
Packit Service fa3ceb
			if sys.hexversion >= 0x3030000:
Packit Service fa3ceb
				cargs['timeout'] = kw['timeout']
Packit Service fa3ceb
				if not 'start_new_session' in kw:
Packit Service fa3ceb
					kw['start_new_session'] = True
Packit Service fa3ceb
			del kw['timeout']
Packit Service fa3ceb
		if 'input' in kw:
Packit Service fa3ceb
			if kw['input']:
Packit Service fa3ceb
				cargs['input'] = kw['input']
Packit Service fa3ceb
				kw['stdin'] = subprocess.PIPE
Packit Service fa3ceb
			del kw['input']
Packit Service fa3ceb
Packit Service fa3ceb
		if 'cwd' in kw:
Packit Service fa3ceb
			if not isinstance(kw['cwd'], str):
Packit Service fa3ceb
				kw['cwd'] = kw['cwd'].abspath()
Packit Service fa3ceb
Packit Service fa3ceb
		encoding = kw.pop('decode_as', default_encoding)
Packit Service fa3ceb
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			ret, out, err = Utils.run_process(cmd, kw, cargs)
Packit Service fa3ceb
		except Exception as e:
Packit Service fa3ceb
			raise Errors.WafError('Execution failure: %s' % str(e), ex=e)
Packit Service fa3ceb
Packit Service fa3ceb
		if not isinstance(out, str):
Packit Service fa3ceb
			out = out.decode(encoding, errors='replace')
Packit Service fa3ceb
		if not isinstance(err, str):
Packit Service fa3ceb
			err = err.decode(encoding, errors='replace')
Packit Service fa3ceb
Packit Service fa3ceb
		if out and quiet != STDOUT and quiet != BOTH:
Packit Service fa3ceb
			self.to_log('out: %s' % out)
Packit Service fa3ceb
		if err and quiet != STDERR and quiet != BOTH:
Packit Service fa3ceb
			self.to_log('err: %s' % err)
Packit Service fa3ceb
Packit Service fa3ceb
		if ret:
Packit Service fa3ceb
			e = Errors.WafError('Command %r returned %r' % (cmd, ret))
Packit Service fa3ceb
			e.returncode = ret
Packit Service fa3ceb
			e.stderr = err
Packit Service fa3ceb
			e.stdout = out
Packit Service fa3ceb
			raise e
Packit Service fa3ceb
Packit Service fa3ceb
		if to_ret == BOTH:
Packit Service fa3ceb
			return (out, err)
Packit Service fa3ceb
		elif to_ret == STDERR:
Packit Service fa3ceb
			return err
Packit Service fa3ceb
		return out
Packit Service fa3ceb
Packit Service fa3ceb
	def fatal(self, msg, ex=None):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Prints an error message in red and stops command execution; this is
Packit Service fa3ceb
		usually used in the configuration section::
Packit Service fa3ceb
Packit Service fa3ceb
			def configure(conf):
Packit Service fa3ceb
				conf.fatal('a requirement is missing')
Packit Service fa3ceb
Packit Service fa3ceb
		:param msg: message to display
Packit Service fa3ceb
		:type msg: string
Packit Service fa3ceb
		:param ex: optional exception object
Packit Service fa3ceb
		:type ex: exception
Packit Service fa3ceb
		:raises: :py:class:`waflib.Errors.ConfigurationError`
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		if self.logger:
Packit Service fa3ceb
			self.logger.info('from %s: %s' % (self.path.abspath(), msg))
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			logfile = self.logger.handlers[0].baseFilename
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			pass
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			if os.environ.get('WAF_PRINT_FAILURE_LOG'):
Packit Service fa3ceb
				# see #1930
Packit Service fa3ceb
				msg = 'Log from (%s):\n%s\n' % (logfile, Utils.readf(logfile))
Packit Service fa3ceb
			else:
Packit Service fa3ceb
				msg = '%s\n(complete log in %s)' % (msg, logfile)
Packit Service fa3ceb
		raise self.errors.ConfigurationError(msg, ex=ex)
Packit Service fa3ceb
Packit Service fa3ceb
	def to_log(self, msg):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Logs information to the logger (if present), or to stderr.
Packit Service fa3ceb
		Empty messages are not printed::
Packit Service fa3ceb
Packit Service fa3ceb
			def build(bld):
Packit Service fa3ceb
				bld.to_log('starting the build')
Packit Service fa3ceb
Packit Service fa3ceb
		Provide a logger on the context class or override this method if necessary.
Packit Service fa3ceb
Packit Service fa3ceb
		:param msg: message
Packit Service fa3ceb
		:type msg: string
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		if not msg:
Packit Service fa3ceb
			return
Packit Service fa3ceb
		if self.logger:
Packit Service fa3ceb
			self.logger.info(msg)
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			sys.stderr.write(str(msg))
Packit Service fa3ceb
			sys.stderr.flush()
Packit Service fa3ceb
Packit Service fa3ceb
Packit Service fa3ceb
	def msg(self, *k, **kw):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Prints a configuration message of the form ``msg: result``.
Packit Service fa3ceb
		The second part of the message will be in colors. The output
Packit Service fa3ceb
		can be disabled easly by setting ``in_msg`` to a positive value::
Packit Service fa3ceb
Packit Service fa3ceb
			def configure(conf):
Packit Service fa3ceb
				self.in_msg = 1
Packit Service fa3ceb
				conf.msg('Checking for library foo', 'ok')
Packit Service fa3ceb
				# no output
Packit Service fa3ceb
Packit Service fa3ceb
		:param msg: message to display to the user
Packit Service fa3ceb
		:type msg: string
Packit Service fa3ceb
		:param result: result to display
Packit Service fa3ceb
		:type result: string or boolean
Packit Service fa3ceb
		:param color: color to use, see :py:const:`waflib.Logs.colors_lst`
Packit Service fa3ceb
		:type color: string
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			msg = kw['msg']
Packit Service fa3ceb
		except KeyError:
Packit Service fa3ceb
			msg = k[0]
Packit Service fa3ceb
Packit Service fa3ceb
		self.start_msg(msg, **kw)
Packit Service fa3ceb
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			result = kw['result']
Packit Service fa3ceb
		except KeyError:
Packit Service fa3ceb
			result = k[1]
Packit Service fa3ceb
Packit Service fa3ceb
		color = kw.get('color')
Packit Service fa3ceb
		if not isinstance(color, str):
Packit Service fa3ceb
			color = result and 'GREEN' or 'YELLOW'
Packit Service fa3ceb
Packit Service fa3ceb
		self.end_msg(result, color, **kw)
Packit Service fa3ceb
Packit Service fa3ceb
	def start_msg(self, *k, **kw):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Prints the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg`
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		if kw.get('quiet'):
Packit Service fa3ceb
			return
Packit Service fa3ceb
Packit Service fa3ceb
		msg = kw.get('msg') or k[0]
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			if self.in_msg:
Packit Service fa3ceb
				self.in_msg += 1
Packit Service fa3ceb
				return
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			self.in_msg = 0
Packit Service fa3ceb
		self.in_msg += 1
Packit Service fa3ceb
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			self.line_just = max(self.line_just, len(msg))
Packit Service fa3ceb
		except AttributeError:
Packit Service fa3ceb
			self.line_just = max(40, len(msg))
Packit Service fa3ceb
		for x in (self.line_just * '-', msg):
Packit Service fa3ceb
			self.to_log(x)
Packit Service fa3ceb
		Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='')
Packit Service fa3ceb
Packit Service fa3ceb
	def end_msg(self, *k, **kw):
Packit Service fa3ceb
		"""Prints the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`"""
Packit Service fa3ceb
		if kw.get('quiet'):
Packit Service fa3ceb
			return
Packit Service fa3ceb
		self.in_msg -= 1
Packit Service fa3ceb
		if self.in_msg:
Packit Service fa3ceb
			return
Packit Service fa3ceb
Packit Service fa3ceb
		result = kw.get('result') or k[0]
Packit Service fa3ceb
Packit Service fa3ceb
		defcolor = 'GREEN'
Packit Service fa3ceb
		if result is True:
Packit Service fa3ceb
			msg = 'ok'
Packit Service fa3ceb
		elif not result:
Packit Service fa3ceb
			msg = 'not found'
Packit Service fa3ceb
			defcolor = 'YELLOW'
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			msg = str(result)
Packit Service fa3ceb
Packit Service fa3ceb
		self.to_log(msg)
Packit Service fa3ceb
		try:
Packit Service fa3ceb
			color = kw['color']
Packit Service fa3ceb
		except KeyError:
Packit Service fa3ceb
			if len(k) > 1 and k[1] in Logs.colors_lst:
Packit Service fa3ceb
				# compatibility waf 1.7
Packit Service fa3ceb
				color = k[1]
Packit Service fa3ceb
			else:
Packit Service fa3ceb
				color = defcolor
Packit Service fa3ceb
		Logs.pprint(color, msg)
Packit Service fa3ceb
Packit Service fa3ceb
	def load_special_tools(self, var, ban=[]):
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		Loads third-party extensions modules for certain programming languages
Packit Service fa3ceb
		by trying to list certain files in the extras/ directory. This method
Packit Service fa3ceb
		is typically called once for a programming language group, see for
Packit Service fa3ceb
		example :py:mod:`waflib.Tools.compiler_c`
Packit Service fa3ceb
Packit Service fa3ceb
		:param var: glob expression, for example 'cxx\\_\\*.py'
Packit Service fa3ceb
		:type var: string
Packit Service fa3ceb
		:param ban: list of exact file names to exclude
Packit Service fa3ceb
		:type ban: list of string
Packit Service fa3ceb
		"""
Packit Service fa3ceb
		if os.path.isdir(waf_dir):
Packit Service fa3ceb
			lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
Packit Service fa3ceb
			for x in lst:
Packit Service fa3ceb
				if not x.name in ban:
Packit Service fa3ceb
					load_tool(x.name.replace('.py', ''))
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			from zipfile import PyZipFile
Packit Service fa3ceb
			waflibs = PyZipFile(waf_dir)
Packit Service fa3ceb
			lst = waflibs.namelist()
Packit Service fa3ceb
			for x in lst:
Packit Service fa3ceb
				if not re.match('waflib/extras/%s' % var.replace('*', '.*'), var):
Packit Service fa3ceb
					continue
Packit Service fa3ceb
				f = os.path.basename(x)
Packit Service fa3ceb
				doban = False
Packit Service fa3ceb
				for b in ban:
Packit Service fa3ceb
					r = b.replace('*', '.*')
Packit Service fa3ceb
					if re.match(r, f):
Packit Service fa3ceb
						doban = True
Packit Service fa3ceb
				if not doban:
Packit Service fa3ceb
					f = f.replace('.py', '')
Packit Service fa3ceb
					load_tool(f)
Packit Service fa3ceb
Packit Service fa3ceb
cache_modules = {}
Packit Service fa3ceb
"""
Packit Service fa3ceb
Dictionary holding already loaded modules (wscript), indexed by their absolute path.
Packit Service fa3ceb
The modules are added automatically by :py:func:`waflib.Context.load_module`
Packit Service fa3ceb
"""
Packit Service fa3ceb
Packit Service fa3ceb
def load_module(path, encoding=None):
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Loads a wscript file as a python module. This method caches results in :py:attr:`waflib.Context.cache_modules`
Packit Service fa3ceb
Packit Service fa3ceb
	:param path: file path
Packit Service fa3ceb
	:type path: string
Packit Service fa3ceb
	:return: Loaded Python module
Packit Service fa3ceb
	:rtype: module
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	try:
Packit Service fa3ceb
		return cache_modules[path]
Packit Service fa3ceb
	except KeyError:
Packit Service fa3ceb
		pass
Packit Service fa3ceb
Packit Service fa3ceb
	module = imp.new_module(WSCRIPT_FILE)
Packit Service fa3ceb
	try:
Packit Service fa3ceb
		code = Utils.readf(path, m='r', encoding=encoding)
Packit Service fa3ceb
	except EnvironmentError:
Packit Service fa3ceb
		raise Errors.WafError('Could not read the file %r' % path)
Packit Service fa3ceb
Packit Service fa3ceb
	module_dir = os.path.dirname(path)
Packit Service fa3ceb
	sys.path.insert(0, module_dir)
Packit Service fa3ceb
	try:
Packit Service fa3ceb
		exec(compile(code, path, 'exec'), module.__dict__)
Packit Service fa3ceb
	finally:
Packit Service fa3ceb
		sys.path.remove(module_dir)
Packit Service fa3ceb
Packit Service fa3ceb
	cache_modules[path] = module
Packit Service fa3ceb
	return module
Packit Service fa3ceb
Packit Service fa3ceb
def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True):
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools`
Packit Service fa3ceb
Packit Service fa3ceb
	:type  tool: string
Packit Service fa3ceb
	:param tool: Name of the tool
Packit Service fa3ceb
	:type  tooldir: list
Packit Service fa3ceb
	:param tooldir: List of directories to search for the tool module
Packit Service fa3ceb
	:type  with_sys_path: boolean
Packit Service fa3ceb
	:param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs
Packit Service fa3ceb
	"""
Packit Service fa3ceb
	if tool == 'java':
Packit Service fa3ceb
		tool = 'javaw' # jython
Packit Service fa3ceb
	else:
Packit Service fa3ceb
		tool = tool.replace('++', 'xx')
Packit Service fa3ceb
Packit Service fa3ceb
	if not with_sys_path:
Packit Service fa3ceb
		back_path = sys.path
Packit Service fa3ceb
		sys.path = []
Packit Service fa3ceb
	try:
Packit Service fa3ceb
		if tooldir:
Packit Service fa3ceb
			assert isinstance(tooldir, list)
Packit Service fa3ceb
			sys.path = tooldir + sys.path
Packit Service fa3ceb
			try:
Packit Service fa3ceb
				__import__(tool)
Packit Service fa3ceb
			except ImportError as e:
Packit Service fa3ceb
				e.waf_sys_path = list(sys.path)
Packit Service fa3ceb
				raise
Packit Service fa3ceb
			finally:
Packit Service fa3ceb
				for d in tooldir:
Packit Service fa3ceb
					sys.path.remove(d)
Packit Service fa3ceb
			ret = sys.modules[tool]
Packit Service fa3ceb
			Context.tools[tool] = ret
Packit Service fa3ceb
			return ret
Packit Service fa3ceb
		else:
Packit Service fa3ceb
			if not with_sys_path:
Packit Service fa3ceb
				sys.path.insert(0, waf_dir)
Packit Service fa3ceb
			try:
Packit Service fa3ceb
				for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'):
Packit Service fa3ceb
					try:
Packit Service fa3ceb
						__import__(x % tool)
Packit Service fa3ceb
						break
Packit Service fa3ceb
					except ImportError:
Packit Service fa3ceb
						x = None
Packit Service fa3ceb
				else: # raise an exception
Packit Service fa3ceb
					__import__(tool)
Packit Service fa3ceb
			except ImportError as e:
Packit Service fa3ceb
				e.waf_sys_path = list(sys.path)
Packit Service fa3ceb
				raise
Packit Service fa3ceb
			finally:
Packit Service fa3ceb
				if not with_sys_path:
Packit Service fa3ceb
					sys.path.remove(waf_dir)
Packit Service fa3ceb
			ret = sys.modules[x % tool]
Packit Service fa3ceb
			Context.tools[tool] = ret
Packit Service fa3ceb
			return ret
Packit Service fa3ceb
	finally:
Packit Service fa3ceb
		if not with_sys_path:
Packit Service fa3ceb
			sys.path += back_path
Packit Service fa3ceb