Merge pull request #618 from mesonbuild/rtrehaul
Rework run_target to mirror custom_target.
This commit is contained in:
commit
cc775d64c9
|
@ -92,6 +92,7 @@ class Backend():
|
|||
raise RuntimeError('No specified compiler can handle file ' + src)
|
||||
|
||||
def get_target_filename(self, target):
|
||||
assert(isinstance(target, (build.BuildTarget, build.CustomTarget)))
|
||||
targetdir = self.get_target_dir(target)
|
||||
fname = target.get_filename()
|
||||
if isinstance(fname, list):
|
||||
|
@ -101,6 +102,9 @@ class Backend():
|
|||
filename = os.path.join(targetdir, fname)
|
||||
return filename
|
||||
|
||||
def get_target_filename_abs(self, target):
|
||||
return os.path.join(self.environment.get_build_dir(), self.get_target_filename(target))
|
||||
|
||||
def get_target_filename_for_linking(self, target):
|
||||
# On some platforms (msvc for instance), the file that is used for
|
||||
# dynamic linking is not the same as the dynamic library itself. This
|
||||
|
|
|
@ -347,11 +347,8 @@ int dummy;
|
|||
if isinstance(s, build.GeneratedList):
|
||||
self.generate_genlist_for_target(s, target, outfile)
|
||||
|
||||
def generate_custom_target(self, target, outfile):
|
||||
self.custom_target_generator_inputs(target, outfile)
|
||||
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
|
||||
def unwrap_dep_list(self, target):
|
||||
deps = []
|
||||
desc = 'Generating {0} with a {1} command.'
|
||||
for i in target.get_dependencies():
|
||||
# FIXME, should not grab element at zero but rather expand all.
|
||||
if isinstance(i, list):
|
||||
|
@ -360,6 +357,13 @@ int dummy;
|
|||
if isinstance(fname, list):
|
||||
fname = fname[0]
|
||||
deps.append(os.path.join(self.get_target_dir(i), fname))
|
||||
return deps
|
||||
|
||||
def generate_custom_target(self, target, outfile):
|
||||
self.custom_target_generator_inputs(target, outfile)
|
||||
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
|
||||
deps = self.unwrap_dep_list(target)
|
||||
desc = 'Generating {0} with a {1} command.'
|
||||
if target.build_always:
|
||||
deps.append('PHONY')
|
||||
elem = NinjaBuildElement(self.all_outputs, ofilenames, 'CUSTOM_COMMAND', srcs)
|
||||
|
@ -397,19 +401,19 @@ int dummy;
|
|||
|
||||
def generate_run_target(self, target, outfile):
|
||||
runnerscript = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner']
|
||||
deps = []
|
||||
deps = self.unwrap_dep_list(target)
|
||||
arg_strings = []
|
||||
for i in target.args:
|
||||
if isinstance(i, str):
|
||||
arg_strings.append(i)
|
||||
elif isinstance(i, (build.BuildTarget, build.CustomTarget)):
|
||||
relfname = self.get_target_filename(i)
|
||||
deps.append(relfname)
|
||||
arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname))
|
||||
else:
|
||||
mlog.debug(str(i))
|
||||
raise MesonException('Unreachable code in generate_run_target.')
|
||||
elem = NinjaBuildElement(self.all_outputs, target.name, 'CUSTOM_COMMAND', deps)
|
||||
elem.add_dep(deps)
|
||||
cmd = runnerscript + [self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir]
|
||||
texe = target.command
|
||||
try:
|
||||
|
|
|
@ -937,10 +937,11 @@ class CustomTarget:
|
|||
return "@cus"
|
||||
|
||||
class RunTarget:
|
||||
def __init__(self, name, command, args, subdir):
|
||||
def __init__(self, name, command, args, dependencies, subdir):
|
||||
self.name = name
|
||||
self.command = command
|
||||
self.args = args
|
||||
self.dependencies = dependencies
|
||||
self.subdir = subdir
|
||||
|
||||
def get_id(self):
|
||||
|
@ -950,7 +951,7 @@ class RunTarget:
|
|||
return self.name
|
||||
|
||||
def get_dependencies(self):
|
||||
return []
|
||||
return self.dependencies
|
||||
|
||||
def get_generated_sources(self):
|
||||
return []
|
||||
|
|
|
@ -23,11 +23,13 @@ from . import compilers
|
|||
from .wrap import wrap
|
||||
from . import mesonlib
|
||||
|
||||
import os, sys, platform, subprocess, shutil, uuid, re
|
||||
import os, sys, subprocess, shutil, uuid, re
|
||||
from functools import wraps
|
||||
|
||||
import importlib
|
||||
|
||||
run_depr_printed = False
|
||||
|
||||
class InterpreterException(mesonlib.MesonException):
|
||||
pass
|
||||
|
||||
|
@ -473,6 +475,7 @@ class BuildTargetHolder(InterpreterObject):
|
|||
'extract_all_objects' : self.extract_all_objects_method,
|
||||
'get_id': self.get_id_method,
|
||||
'outdir' : self.outdir_method,
|
||||
'full_path' : self.full_path_method,
|
||||
'private_dir_include' : self.private_dir_include_method,
|
||||
})
|
||||
|
||||
|
@ -483,6 +486,9 @@ class BuildTargetHolder(InterpreterObject):
|
|||
return IncludeDirsHolder(build.IncludeDirs('', [], False,
|
||||
[self.interpreter.backend.get_target_private_dir(self.held_object)]))
|
||||
|
||||
def full_path_method(self, args, kwargs):
|
||||
return self.interpreter.backend.get_target_filename_abs(self.held_object)
|
||||
|
||||
def outdir_method(self, args, kwargs):
|
||||
return self.interpreter.backend.get_target_dir(self.held_object)
|
||||
|
||||
|
@ -514,19 +520,19 @@ class JarHolder(BuildTargetHolder):
|
|||
super().__init__(target, interp)
|
||||
|
||||
class CustomTargetHolder(InterpreterObject):
|
||||
def __init__(self, object_to_hold):
|
||||
def __init__(self, object_to_hold, interp):
|
||||
super().__init__()
|
||||
self.held_object = object_to_hold
|
||||
self.interpreter = interp
|
||||
self.methods.update({'full_path' : self.full_path_method,
|
||||
})
|
||||
|
||||
def is_cross(self):
|
||||
return self.held_object.is_cross()
|
||||
|
||||
def extract_objects_method(self, args, kwargs):
|
||||
gobjs = self.held_object.extract_objects(args)
|
||||
return GeneratedObjectsHolder(gobjs)
|
||||
def full_path_method(self, args, kwargs):
|
||||
return self.interpreter.backend.get_target_filename_abs(self.held_object)
|
||||
|
||||
class RunTargetHolder(InterpreterObject):
|
||||
def __init__(self, name, command, args, subdir):
|
||||
self.held_object = build.RunTarget(name, command, args, subdir)
|
||||
def __init__(self, name, command, args, dependencies, subdir):
|
||||
self.held_object = build.RunTarget(name, command, args, dependencies, subdir)
|
||||
|
||||
class Test(InterpreterObject):
|
||||
def __init__(self, name, suite, exe, is_parallel, cmd_args, env, should_fail, valgrind_args, timeout, workdir):
|
||||
|
@ -1069,7 +1075,7 @@ class Interpreter():
|
|||
for v in invalues:
|
||||
if isinstance(v, build.CustomTarget):
|
||||
self.add_target(v.name, v)
|
||||
outvalues.append(CustomTargetHolder(v))
|
||||
outvalues.append(CustomTargetHolder(v, self))
|
||||
elif isinstance(v, int) or isinstance(v, str):
|
||||
outvalues.append(v)
|
||||
elif isinstance(v, build.Executable):
|
||||
|
@ -1754,16 +1760,32 @@ class Interpreter():
|
|||
if len(args) != 1:
|
||||
raise InterpreterException('Incorrect number of arguments')
|
||||
name = args[0]
|
||||
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, kwargs))
|
||||
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, kwargs), self)
|
||||
self.add_target(name, tg.held_object)
|
||||
return tg
|
||||
|
||||
@noKwargs
|
||||
def func_run_target(self, node, args, kwargs):
|
||||
if len(args) < 2:
|
||||
raise InterpreterException('Incorrect number of arguments')
|
||||
global run_depr_printed
|
||||
if len(args) > 1:
|
||||
if not run_depr_printed:
|
||||
mlog.log(mlog.red('DEPRECATION'), 'positional version of run_target is deprecated, use the keyword version instead.')
|
||||
run_depr_printed = True
|
||||
if 'command' in kwargs:
|
||||
raise InterpreterException('Can not have command both in positional and keyword arguments.')
|
||||
all_args = args[1:]
|
||||
deps = []
|
||||
elif len(args) == 1:
|
||||
if not 'command' in kwargs:
|
||||
raise InterpreterException('Missing "command" keyword argument')
|
||||
all_args = kwargs['command']
|
||||
deps = kwargs.get('depends', [])
|
||||
if not isinstance(deps, list):
|
||||
deps = [deps]
|
||||
else:
|
||||
raise InterpreterException('Run_target needs at least one positional argument.')
|
||||
|
||||
cleaned_args = []
|
||||
for i in args:
|
||||
for i in all_args:
|
||||
try:
|
||||
i = i.held_object
|
||||
except AttributeError:
|
||||
|
@ -1772,10 +1794,21 @@ class Interpreter():
|
|||
mlog.debug('Wrong type:', str(i))
|
||||
raise InterpreterException('Invalid argument to run_target.')
|
||||
cleaned_args.append(i)
|
||||
name = cleaned_args[0]
|
||||
command = cleaned_args[1]
|
||||
cmd_args = cleaned_args[2:]
|
||||
tg = RunTargetHolder(name, command, cmd_args, self.subdir)
|
||||
name = args[0]
|
||||
if not isinstance(name, str):
|
||||
raise InterpreterException('First argument must be a string.')
|
||||
cleaned_deps = []
|
||||
for d in deps:
|
||||
try:
|
||||
d = d.held_object
|
||||
except AttributeError:
|
||||
pass
|
||||
if not isinstance(d, (build.BuildTarget, build.CustomTarget)):
|
||||
raise InterpreterException('Depends items must be build targets.')
|
||||
cleaned_deps.append(d)
|
||||
command = cleaned_args[0]
|
||||
cmd_args = cleaned_args[1:]
|
||||
tg = RunTargetHolder(name, command, cmd_args, cleaned_deps, self.subdir)
|
||||
self.add_target(name, tg.held_object)
|
||||
return tg
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ class I18nModule:
|
|||
raise coredata.MesonException('List of languages empty.')
|
||||
extra_args = mesonlib.stringlistify(kwargs.get('args', []))
|
||||
potargs = [state.environment.get_build_command(), '--internal', 'gettext', 'pot', packagename] + extra_args
|
||||
pottarget = build.RunTarget(packagename + '-pot', sys.executable, potargs, state.subdir)
|
||||
pottarget = build.RunTarget(packagename + '-pot', sys.executable, potargs, [], state.subdir)
|
||||
gmoargs = [state.environment.get_build_command(), '--internal', 'gettext', 'gen_gmo'] + languages
|
||||
gmotarget = build.RunTarget(packagename + '-gmo', sys.executable, gmoargs, state.subdir)
|
||||
gmotarget = build.RunTarget(packagename + '-gmo', sys.executable, gmoargs, [], state.subdir)
|
||||
installcmd = [sys.executable,
|
||||
state.environment.get_build_command(),
|
||||
'--internal',
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
open(sys.argv[2], 'wb').write(open(sys.argv[1], 'rb').read())
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
plain_arg = sys.argv[1]
|
||||
_, filename, _ = plain_arg.split(':')
|
||||
try:
|
||||
content = open(filename, 'rb').read()
|
||||
except FileNotFoundError:
|
||||
print('Could not open file. Missing dependency?')
|
||||
sys.exit(1)
|
||||
print('File opened, pretending to send it somewhere.')
|
||||
print(len(content), 'bytes uploaded')
|
|
@ -1,12 +1,36 @@
|
|||
project('run target', 'c')
|
||||
|
||||
run_target('mycommand', 'scripts/script.sh')
|
||||
# deprecated format, fix once we remove support for it.
|
||||
run_target('mycommand','scripts/script.sh')
|
||||
|
||||
# Make it possible to run built programs.
|
||||
# In cross builds exe_wrapper should be added if it exists.
|
||||
|
||||
exe = executable('helloprinter', 'helloprinter.c')
|
||||
run_target('runhello', exe, 'argument')
|
||||
run_target('runhello',
|
||||
command : [exe, 'argument'])
|
||||
|
||||
converter = find_program('converter.py')
|
||||
|
||||
hex = custom_target('exe.hex',
|
||||
input : exe,
|
||||
output : 'exe.hex',
|
||||
command : [converter, '@INPUT@', '@OUTPUT@',
|
||||
],
|
||||
)
|
||||
|
||||
# These emulates the Arduino flasher application. It sandwiches the filename inside
|
||||
# a packed argument. Thus we need to declare it manually.
|
||||
run_target('upload',
|
||||
command : ['fakeburner.py', 'x:@0@:y'.format(exe.full_path())],
|
||||
depends : exe,
|
||||
)
|
||||
|
||||
run_target('upload2',
|
||||
command : ['fakeburner.py', 'x:@0@:y'.format(hex.full_path())],
|
||||
depends : hex,
|
||||
)
|
||||
|
||||
python3 = find_program('python3')
|
||||
run_target('py3hi', python3, '-c', 'print("I am Python3.")')
|
||||
run_target('py3hi',
|
||||
command : [python3, '-c', 'print("I am Python3.")'])
|
||||
|
|
Loading…
Reference in New Issue