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)
|
raise RuntimeError('No specified compiler can handle file ' + src)
|
||||||
|
|
||||||
def get_target_filename(self, target):
|
def get_target_filename(self, target):
|
||||||
|
assert(isinstance(target, (build.BuildTarget, build.CustomTarget)))
|
||||||
targetdir = self.get_target_dir(target)
|
targetdir = self.get_target_dir(target)
|
||||||
fname = target.get_filename()
|
fname = target.get_filename()
|
||||||
if isinstance(fname, list):
|
if isinstance(fname, list):
|
||||||
|
@ -101,6 +102,9 @@ class Backend():
|
||||||
filename = os.path.join(targetdir, fname)
|
filename = os.path.join(targetdir, fname)
|
||||||
return filename
|
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):
|
def get_target_filename_for_linking(self, target):
|
||||||
# On some platforms (msvc for instance), the file that is used for
|
# On some platforms (msvc for instance), the file that is used for
|
||||||
# dynamic linking is not the same as the dynamic library itself. This
|
# dynamic linking is not the same as the dynamic library itself. This
|
||||||
|
|
|
@ -347,11 +347,8 @@ int dummy;
|
||||||
if isinstance(s, build.GeneratedList):
|
if isinstance(s, build.GeneratedList):
|
||||||
self.generate_genlist_for_target(s, target, outfile)
|
self.generate_genlist_for_target(s, target, outfile)
|
||||||
|
|
||||||
def generate_custom_target(self, target, outfile):
|
def unwrap_dep_list(self, target):
|
||||||
self.custom_target_generator_inputs(target, outfile)
|
|
||||||
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
|
|
||||||
deps = []
|
deps = []
|
||||||
desc = 'Generating {0} with a {1} command.'
|
|
||||||
for i in target.get_dependencies():
|
for i in target.get_dependencies():
|
||||||
# FIXME, should not grab element at zero but rather expand all.
|
# FIXME, should not grab element at zero but rather expand all.
|
||||||
if isinstance(i, list):
|
if isinstance(i, list):
|
||||||
|
@ -360,6 +357,13 @@ int dummy;
|
||||||
if isinstance(fname, list):
|
if isinstance(fname, list):
|
||||||
fname = fname[0]
|
fname = fname[0]
|
||||||
deps.append(os.path.join(self.get_target_dir(i), fname))
|
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:
|
if target.build_always:
|
||||||
deps.append('PHONY')
|
deps.append('PHONY')
|
||||||
elem = NinjaBuildElement(self.all_outputs, ofilenames, 'CUSTOM_COMMAND', srcs)
|
elem = NinjaBuildElement(self.all_outputs, ofilenames, 'CUSTOM_COMMAND', srcs)
|
||||||
|
@ -397,19 +401,19 @@ int dummy;
|
||||||
|
|
||||||
def generate_run_target(self, target, outfile):
|
def generate_run_target(self, target, outfile):
|
||||||
runnerscript = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner']
|
runnerscript = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner']
|
||||||
deps = []
|
deps = self.unwrap_dep_list(target)
|
||||||
arg_strings = []
|
arg_strings = []
|
||||||
for i in target.args:
|
for i in target.args:
|
||||||
if isinstance(i, str):
|
if isinstance(i, str):
|
||||||
arg_strings.append(i)
|
arg_strings.append(i)
|
||||||
elif isinstance(i, (build.BuildTarget, build.CustomTarget)):
|
elif isinstance(i, (build.BuildTarget, build.CustomTarget)):
|
||||||
relfname = self.get_target_filename(i)
|
relfname = self.get_target_filename(i)
|
||||||
deps.append(relfname)
|
|
||||||
arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname))
|
arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname))
|
||||||
else:
|
else:
|
||||||
mlog.debug(str(i))
|
mlog.debug(str(i))
|
||||||
raise MesonException('Unreachable code in generate_run_target.')
|
raise MesonException('Unreachable code in generate_run_target.')
|
||||||
elem = NinjaBuildElement(self.all_outputs, target.name, 'CUSTOM_COMMAND', deps)
|
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]
|
cmd = runnerscript + [self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir]
|
||||||
texe = target.command
|
texe = target.command
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -937,10 +937,11 @@ class CustomTarget:
|
||||||
return "@cus"
|
return "@cus"
|
||||||
|
|
||||||
class RunTarget:
|
class RunTarget:
|
||||||
def __init__(self, name, command, args, subdir):
|
def __init__(self, name, command, args, dependencies, subdir):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.command = command
|
self.command = command
|
||||||
self.args = args
|
self.args = args
|
||||||
|
self.dependencies = dependencies
|
||||||
self.subdir = subdir
|
self.subdir = subdir
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
|
@ -950,7 +951,7 @@ class RunTarget:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_dependencies(self):
|
def get_dependencies(self):
|
||||||
return []
|
return self.dependencies
|
||||||
|
|
||||||
def get_generated_sources(self):
|
def get_generated_sources(self):
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -23,11 +23,13 @@ from . import compilers
|
||||||
from .wrap import wrap
|
from .wrap import wrap
|
||||||
from . import mesonlib
|
from . import mesonlib
|
||||||
|
|
||||||
import os, sys, platform, subprocess, shutil, uuid, re
|
import os, sys, subprocess, shutil, uuid, re
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
|
run_depr_printed = False
|
||||||
|
|
||||||
class InterpreterException(mesonlib.MesonException):
|
class InterpreterException(mesonlib.MesonException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -473,6 +475,7 @@ class BuildTargetHolder(InterpreterObject):
|
||||||
'extract_all_objects' : self.extract_all_objects_method,
|
'extract_all_objects' : self.extract_all_objects_method,
|
||||||
'get_id': self.get_id_method,
|
'get_id': self.get_id_method,
|
||||||
'outdir' : self.outdir_method,
|
'outdir' : self.outdir_method,
|
||||||
|
'full_path' : self.full_path_method,
|
||||||
'private_dir_include' : self.private_dir_include_method,
|
'private_dir_include' : self.private_dir_include_method,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -483,6 +486,9 @@ class BuildTargetHolder(InterpreterObject):
|
||||||
return IncludeDirsHolder(build.IncludeDirs('', [], False,
|
return IncludeDirsHolder(build.IncludeDirs('', [], False,
|
||||||
[self.interpreter.backend.get_target_private_dir(self.held_object)]))
|
[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):
|
def outdir_method(self, args, kwargs):
|
||||||
return self.interpreter.backend.get_target_dir(self.held_object)
|
return self.interpreter.backend.get_target_dir(self.held_object)
|
||||||
|
|
||||||
|
@ -514,19 +520,19 @@ class JarHolder(BuildTargetHolder):
|
||||||
super().__init__(target, interp)
|
super().__init__(target, interp)
|
||||||
|
|
||||||
class CustomTargetHolder(InterpreterObject):
|
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.held_object = object_to_hold
|
||||||
|
self.interpreter = interp
|
||||||
|
self.methods.update({'full_path' : self.full_path_method,
|
||||||
|
})
|
||||||
|
|
||||||
def is_cross(self):
|
def full_path_method(self, args, kwargs):
|
||||||
return self.held_object.is_cross()
|
return self.interpreter.backend.get_target_filename_abs(self.held_object)
|
||||||
|
|
||||||
def extract_objects_method(self, args, kwargs):
|
|
||||||
gobjs = self.held_object.extract_objects(args)
|
|
||||||
return GeneratedObjectsHolder(gobjs)
|
|
||||||
|
|
||||||
class RunTargetHolder(InterpreterObject):
|
class RunTargetHolder(InterpreterObject):
|
||||||
def __init__(self, name, command, args, subdir):
|
def __init__(self, name, command, args, dependencies, subdir):
|
||||||
self.held_object = build.RunTarget(name, command, args, subdir)
|
self.held_object = build.RunTarget(name, command, args, dependencies, subdir)
|
||||||
|
|
||||||
class Test(InterpreterObject):
|
class Test(InterpreterObject):
|
||||||
def __init__(self, name, suite, exe, is_parallel, cmd_args, env, should_fail, valgrind_args, timeout, workdir):
|
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:
|
for v in invalues:
|
||||||
if isinstance(v, build.CustomTarget):
|
if isinstance(v, build.CustomTarget):
|
||||||
self.add_target(v.name, v)
|
self.add_target(v.name, v)
|
||||||
outvalues.append(CustomTargetHolder(v))
|
outvalues.append(CustomTargetHolder(v, self))
|
||||||
elif isinstance(v, int) or isinstance(v, str):
|
elif isinstance(v, int) or isinstance(v, str):
|
||||||
outvalues.append(v)
|
outvalues.append(v)
|
||||||
elif isinstance(v, build.Executable):
|
elif isinstance(v, build.Executable):
|
||||||
|
@ -1754,16 +1760,32 @@ class Interpreter():
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
raise InterpreterException('Incorrect number of arguments')
|
raise InterpreterException('Incorrect number of arguments')
|
||||||
name = args[0]
|
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)
|
self.add_target(name, tg.held_object)
|
||||||
return tg
|
return tg
|
||||||
|
|
||||||
@noKwargs
|
|
||||||
def func_run_target(self, node, args, kwargs):
|
def func_run_target(self, node, args, kwargs):
|
||||||
if len(args) < 2:
|
global run_depr_printed
|
||||||
raise InterpreterException('Incorrect number of arguments')
|
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 = []
|
cleaned_args = []
|
||||||
for i in args:
|
for i in all_args:
|
||||||
try:
|
try:
|
||||||
i = i.held_object
|
i = i.held_object
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -1772,10 +1794,21 @@ class Interpreter():
|
||||||
mlog.debug('Wrong type:', str(i))
|
mlog.debug('Wrong type:', str(i))
|
||||||
raise InterpreterException('Invalid argument to run_target.')
|
raise InterpreterException('Invalid argument to run_target.')
|
||||||
cleaned_args.append(i)
|
cleaned_args.append(i)
|
||||||
name = cleaned_args[0]
|
name = args[0]
|
||||||
command = cleaned_args[1]
|
if not isinstance(name, str):
|
||||||
cmd_args = cleaned_args[2:]
|
raise InterpreterException('First argument must be a string.')
|
||||||
tg = RunTargetHolder(name, command, cmd_args, self.subdir)
|
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)
|
self.add_target(name, tg.held_object)
|
||||||
return tg
|
return tg
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ class I18nModule:
|
||||||
raise coredata.MesonException('List of languages empty.')
|
raise coredata.MesonException('List of languages empty.')
|
||||||
extra_args = mesonlib.stringlistify(kwargs.get('args', []))
|
extra_args = mesonlib.stringlistify(kwargs.get('args', []))
|
||||||
potargs = [state.environment.get_build_command(), '--internal', 'gettext', 'pot', packagename] + extra_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
|
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,
|
installcmd = [sys.executable,
|
||||||
state.environment.get_build_command(),
|
state.environment.get_build_command(),
|
||||||
'--internal',
|
'--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')
|
project('run target', 'c')
|
||||||
|
|
||||||
|
# deprecated format, fix once we remove support for it.
|
||||||
run_target('mycommand','scripts/script.sh')
|
run_target('mycommand','scripts/script.sh')
|
||||||
|
|
||||||
# Make it possible to run built programs.
|
# Make it possible to run built programs.
|
||||||
# In cross builds exe_wrapper should be added if it exists.
|
# In cross builds exe_wrapper should be added if it exists.
|
||||||
|
|
||||||
exe = executable('helloprinter', 'helloprinter.c')
|
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')
|
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