2013-04-01 22:33:46 +02:00
|
|
|
import re
|
2011-09-08 16:13:40 +01:00
|
|
|
import subprocess
|
2013-04-01 22:33:46 +02:00
|
|
|
|
|
|
|
|
# import feature, taskgen_method, before_method, task_gen
|
|
|
|
|
from waflib import TaskGen, Node, Task, Utils, Build, Options, Logs, Task
|
|
|
|
|
debug = Logs.debug
|
|
|
|
|
error = Logs.error
|
2009-09-21 10:59:21 +01:00
|
|
|
|
|
|
|
|
import shellcmd
|
2011-09-08 16:13:40 +01:00
|
|
|
#shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy
|
2009-09-21 10:59:21 +01:00
|
|
|
shellcmd.debug = debug
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
arg_rx = re.compile(r"(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})", re.M)
|
|
|
|
|
|
2018-08-24 18:02:14 -07:00
|
|
|
class command(Task.Task):
|
2009-09-21 10:59:21 +01:00
|
|
|
color = "BLUE"
|
|
|
|
|
def __init__(self, env, generator):
|
2011-09-08 16:13:40 +01:00
|
|
|
Task.Task.__init__(self, env=env, normal=1, generator=generator)
|
2009-09-21 10:59:21 +01:00
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
"string to display to the user"
|
|
|
|
|
env = self.env
|
2015-06-23 14:34:53 +02:00
|
|
|
src_str = ' '.join([a.bldpath() for a in self.inputs])
|
|
|
|
|
tgt_str = ' '.join([a.bldpath() for a in self.outputs])
|
2009-09-21 10:59:21 +01:00
|
|
|
if self.outputs:
|
|
|
|
|
sep = ' -> '
|
|
|
|
|
else:
|
|
|
|
|
sep = ''
|
|
|
|
|
|
|
|
|
|
pipeline = shellcmd.Pipeline()
|
|
|
|
|
pipeline.parse(self.generator.command)
|
|
|
|
|
cmd = pipeline.get_abbreviated_command()
|
2018-03-14 22:05:53 -07:00
|
|
|
return 'command (%s): %s%s%s' % (cmd, src_str, sep, tgt_str)
|
2009-09-21 10:59:21 +01:00
|
|
|
|
|
|
|
|
def _subst_arg(self, arg, direction, namespace):
|
|
|
|
|
"""
|
|
|
|
|
@param arg: the command argument (or stdin/stdout/stderr) to substitute
|
|
|
|
|
@param direction: direction of the argument: 'in', 'out', or None
|
|
|
|
|
"""
|
|
|
|
|
def repl(match):
|
|
|
|
|
if match.group('dollar'):
|
|
|
|
|
return "$"
|
|
|
|
|
elif match.group('subst'):
|
|
|
|
|
var = match.group('var')
|
|
|
|
|
code = match.group('code')
|
|
|
|
|
result = eval(var+code, namespace)
|
|
|
|
|
if isinstance(result, Node.Node):
|
|
|
|
|
if var == 'TGT':
|
2011-09-08 16:13:40 +01:00
|
|
|
return result.get_bld().abspath()
|
2009-09-21 10:59:21 +01:00
|
|
|
elif var == 'SRC':
|
2011-09-08 16:13:40 +01:00
|
|
|
return result.srcpath()
|
2009-09-21 10:59:21 +01:00
|
|
|
else:
|
|
|
|
|
raise ValueError("Bad subst variable %r" % var)
|
|
|
|
|
elif result is self.inputs:
|
|
|
|
|
if len(self.inputs) == 1:
|
2011-09-08 16:13:40 +01:00
|
|
|
return result[0].srcpath()
|
2009-09-21 10:59:21 +01:00
|
|
|
else:
|
|
|
|
|
raise ValueError("${SRC} requested but have multiple sources; which one?")
|
|
|
|
|
elif result is self.outputs:
|
|
|
|
|
if len(self.outputs) == 1:
|
2011-09-08 16:13:40 +01:00
|
|
|
return result[0].get_bld().abspath()
|
2009-09-21 10:59:21 +01:00
|
|
|
else:
|
|
|
|
|
raise ValueError("${TGT} requested but have multiple targets; which one?")
|
2011-09-08 16:13:40 +01:00
|
|
|
elif isinstance(result, list):
|
|
|
|
|
assert len(result) == 1
|
|
|
|
|
return result[0]
|
2009-09-21 10:59:21 +01:00
|
|
|
else:
|
|
|
|
|
return result
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
return arg_rx.sub(repl, arg)
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
pipeline = shellcmd.Pipeline()
|
|
|
|
|
pipeline.parse(self.generator.command)
|
|
|
|
|
namespace = self.env.get_merged_dict()
|
|
|
|
|
if self.generator.variables is not None:
|
|
|
|
|
namespace.update(self.generator.variables)
|
|
|
|
|
namespace.update(env=self.env, SRC=self.inputs, TGT=self.outputs)
|
|
|
|
|
for cmd in pipeline.pipeline:
|
|
|
|
|
if isinstance(cmd, shellcmd.Command):
|
2015-09-03 21:14:55 -07:00
|
|
|
if isinstance(cmd.stdin, str):
|
2009-09-21 10:59:21 +01:00
|
|
|
cmd.stdin = self._subst_arg(cmd.stdin, 'in', namespace)
|
2015-09-03 21:14:55 -07:00
|
|
|
if isinstance(cmd.stdout, str):
|
2009-09-21 10:59:21 +01:00
|
|
|
cmd.stdout = self._subst_arg(cmd.stdout, 'out', namespace)
|
2015-09-03 21:14:55 -07:00
|
|
|
if isinstance(cmd.stderr, str):
|
2009-09-21 10:59:21 +01:00
|
|
|
cmd.stderr = self._subst_arg(cmd.stderr, 'out', namespace)
|
2015-09-03 21:14:55 -07:00
|
|
|
for argI in range(len(cmd.argv)):
|
2009-09-21 10:59:21 +01:00
|
|
|
cmd.argv[argI] = self._subst_arg(cmd.argv[argI], None, namespace)
|
|
|
|
|
if cmd.env_vars is not None:
|
|
|
|
|
env_vars = dict()
|
2015-09-03 21:14:55 -07:00
|
|
|
for name, value in cmd.env_vars.items():
|
2009-09-21 10:59:21 +01:00
|
|
|
env_vars[name] = self._subst_arg(value, None, namespace)
|
|
|
|
|
cmd.env_vars = env_vars
|
|
|
|
|
elif isinstance(cmd, shellcmd.Chdir):
|
|
|
|
|
cmd.dir = self._subst_arg(cmd.dir, None, namespace)
|
|
|
|
|
return pipeline.run(verbose=(Options.options.verbose > 0))
|
|
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
@TaskGen.taskgen_method
|
|
|
|
|
@TaskGen.feature('command')
|
2009-09-21 10:59:21 +01:00
|
|
|
def init_command(self):
|
|
|
|
|
Utils.def_attrs(self,
|
2011-09-12 16:19:24 +01:00
|
|
|
# other variables that can be used in the command: ${VARIABLE}
|
|
|
|
|
variables = None,
|
|
|
|
|
rule='')
|
2009-09-21 10:59:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
@TaskGen.feature('command')
|
|
|
|
|
@TaskGen.after_method('process_rule')
|
2009-09-21 10:59:21 +01:00
|
|
|
def apply_command(self):
|
2011-09-08 16:13:40 +01:00
|
|
|
#self.meths.remove('apply_core')
|
2009-09-21 10:59:21 +01:00
|
|
|
# create the task
|
|
|
|
|
task = self.create_task('command')
|
|
|
|
|
setattr(task, "dep_vars", getattr(self, "dep_vars", None))
|
|
|
|
|
# process the sources
|
|
|
|
|
inputs = []
|
2011-09-08 16:13:40 +01:00
|
|
|
for node in self.source:
|
|
|
|
|
inputs.append(node)
|
2009-09-21 10:59:21 +01:00
|
|
|
task.set_inputs(inputs)
|
|
|
|
|
task.set_outputs([self.path.find_or_declare(tgt) for tgt in self.to_list(self.target)])
|
2011-09-08 16:13:40 +01:00
|
|
|
self.source = ''
|
2009-09-21 10:59:21 +01:00
|
|
|
#Task.file_deps = Task.extract_deps
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
# class command_taskgen(task_gen):
|
|
|
|
|
# def __init__(self, *k, **kw):
|
|
|
|
|
# task_gen.__init__(self, *k, **kw)
|
|
|
|
|
# self.features.append('command')
|