aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manual tests/9 nostdlib/meson.build4
-rw-r--r--mesonbuild/backend/backends.py11
-rw-r--r--mesonbuild/backend/ninjabackend.py22
-rw-r--r--mesonbuild/build.py5
-rw-r--r--mesonbuild/compilers.py30
-rw-r--r--mesonbuild/dependencies.py6
-rw-r--r--mesonbuild/environment.py3
-rw-r--r--mesonbuild/interpreter.py88
-rw-r--r--mesonbuild/modules/i18n.py4
-rw-r--r--mesonbuild/scripts/meson_install.py22
-rw-r--r--test cases/common/58 run target/converter.py5
-rwxr-xr-xtest cases/common/58 run target/fakeburner.py13
-rw-r--r--test cases/common/58 run target/meson.build30
-rw-r--r--test cases/failing/29 no crossprop/meson.build3
14 files changed, 204 insertions, 42 deletions
diff --git a/manual tests/9 nostdlib/meson.build b/manual tests/9 nostdlib/meson.build
index 3ef743e..9c5f949 100644
--- a/manual tests/9 nostdlib/meson.build
+++ b/manual tests/9 nostdlib/meson.build
@@ -1,5 +1,9 @@
project('own libc', 'c')
+# Not related to this test, but could not find a better place for this test.
+assert(meson.get_cross_property('nonexisting', 'defaultvalue') == 'defaultvalue',
+ 'Cross prop getting is broken.')
+
# A simple project that uses its own libc.
# Note that we don't need to specify anything, the flags to use
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index ded3ea2..d2693b2 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -83,8 +83,9 @@ class Backend():
return i
raise RuntimeError('No compiler for language ' + lang)
- def get_compiler_for_source(self, src):
- for i in self.build.compilers:
+ def get_compiler_for_source(self, src, is_cross):
+ comp = self.build.cross_compilers if is_cross else self.build.compilers
+ for i in comp:
if i.can_compile(src):
return i
if isinstance(src, mesonlib.File):
@@ -92,6 +93,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 +103,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
@@ -133,7 +138,7 @@ class Backend():
abs_files = []
result = []
for src in unity_src:
- comp = self.get_compiler_for_source(src)
+ comp = self.get_compiler_for_source(src, target.is_cross)
language = comp.get_language()
suffix = '.' + comp.get_default_suffix()
if language not in langlist:
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index f6a3c75..b84a144 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -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:
@@ -676,7 +680,7 @@ int dummy;
outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
class_list = []
- compiler = self.get_compiler_for_source(src_list[0])
+ compiler = self.get_compiler_for_source(src_list[0], False)
assert(compiler.get_language() == 'java')
c = 'c'
m = ''
@@ -727,7 +731,7 @@ int dummy;
fname = target.get_filename()
outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
- compiler = self.get_compiler_for_source(src_list[0])
+ compiler = self.get_compiler_for_source(src_list[0], False)
assert(compiler.get_language() == 'cs')
rel_srcs = [s.rel_to_builddir(self.build_to_src) for s in src_list]
deps = []
@@ -1435,7 +1439,7 @@ rule FORTRAN_DEP_HACK
if isinstance(src, RawFilename) and src.fname.endswith('.h'):
raise RuntimeError('Fug')
extra_orderdeps = []
- compiler = self.get_compiler_for_source(src)
+ compiler = self.get_compiler_for_source(src, target.is_cross)
commands = []
# The first thing is implicit include directories: source, build and private.
commands += compiler.get_include_args(self.get_target_private_dir(target), False)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 1ff834c..b610bb8 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1088,10 +1088,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 __repr__(self):
@@ -1105,7 +1106,7 @@ class RunTarget:
return self.name
def get_dependencies(self):
- return []
+ return self.dependencies
def get_generated_sources(self):
return []
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index a091dc9..55a4384 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -129,6 +129,10 @@ msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib',
'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib',
'uuid.lib', 'comdlg32.lib', 'advapi32.lib']
+gnu_color_args = {'auto' : ['-fdiagnostics-color=auto'],
+ 'always': ['-fdiagnostics-color=always'],
+ 'never' : ['-fdiagnostics-color=never'],
+ }
base_options = {
'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled headers', True),
@@ -144,6 +148,9 @@ base_options = {
'b_coverage': coredata.UserBooleanOption('b_coverage',
'Enable coverage tracking.',
False),
+ 'b_colorout' : coredata.UserComboOption('b_colorout', 'Use colored output',
+ ['auto', 'always', 'never'],
+ 'always'),
}
def sanitizer_compile_args(value):
@@ -169,6 +176,10 @@ def get_base_compile_args(options, compiler):
except KeyError:
pass
try:
+ args += compiler.get_colorout_args(options['b_colorout'].value)
+ except KeyError:
+ pass
+ try:
args += sanitizer_compile_args(options['b_sanitize'].value)
except KeyError:
pass
@@ -332,6 +343,9 @@ class Compiler():
extra_flags += environment.cross_info.config['properties'].get(lang_link_args_key, [])
return extra_flags
+ def get_colorout_args(self, colortype):
+ return []
+
class CCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
super().__init__(exelist, version)
@@ -1643,10 +1657,16 @@ class GnuCCompiler(CCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
- self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
+ self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
+ 'b_colorout']
if self.gcc_type != GCC_OSX:
self.base_options.append('b_lundef')
+ def get_colorout_args(self, colortype):
+ if mesonlib.version_compare(self.version, '>=4.9.0'):
+ return gnu_color_args[colortype][:]
+ return []
+
def get_pic_args(self):
if self.gcc_type == GCC_MINGW:
return [] # On Window gcc defaults to fpic being always on.
@@ -1826,10 +1846,16 @@ class GnuCPPCompiler(CPPCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
- self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
+ self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
+ 'b_colorout']
if self.gcc_type != GCC_OSX:
self.base_options.append('b_lundef')
+ def get_colorout_args(self, colortype):
+ if mesonlib.version_compare(self.version, '>=4.9.0'):
+ return gnu_color_args[colortype][:]
+ return []
+
def get_always_args(self):
return ['-pipe']
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
index 544291b..2b77706 100644
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -1105,11 +1105,13 @@ class Python3Dependency(Dependency):
super().__init__()
self.name = 'python3'
self.is_found = False
+ self.version = "3.something_maybe"
try:
pkgdep = PkgConfigDependency('python3', environment, kwargs)
if pkgdep.found():
self.cargs = pkgdep.cargs
self.libs = pkgdep.libs
+ self.version = pkgdep.get_version()
self.is_found = True
return
except Exception:
@@ -1127,6 +1129,7 @@ class Python3Dependency(Dependency):
self.libs = ['-L{}/libs'.format(basedir),
'-lpython{}'.format(vernum)]
self.is_found = True
+ self.version = sysconfig.get_config_var('py_version_short')
elif mesonlib.is_osx():
# In OSX the Python 3 framework does not have a version
# number in its name.
@@ -1146,6 +1149,9 @@ class Python3Dependency(Dependency):
def get_link_args(self):
return self.libs
+ def get_version(self):
+ return self.version
+
def get_dep_identifier(name, kwargs):
elements = [name]
modlist = kwargs.get('modules', [])
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index f74b588..47414ca 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -770,6 +770,9 @@ class CrossBuildInfo():
def get_stdlib(self, language):
return self.config['properties'][language + '_stdlib']
+ def get_properties(self):
+ return self.config['properties']
+
# Wehn compiling a cross compiler we use the native compiler for everything.
# But not when cross compiling a cross compiler.
def need_cross_compiler(self):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index c997e0e..df4cb0d 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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):
@@ -860,6 +866,7 @@ class MesonMain(InterpreterObject):
'install_dependency_manifest': self.install_dependency_manifest_method,
'project_version': self.project_version_method,
'project_name' : self.project_name_method,
+ 'get_cross_property': self.get_cross_property_method,
})
def add_install_script_method(self, args, kwargs):
@@ -959,6 +966,20 @@ class MesonMain(InterpreterObject):
def project_name_method(self, args, kwargs):
return self.interpreter.active_projectname
+ def get_cross_property_method(self, args, kwargs):
+ if len(args) < 1 or len(args) > 2:
+ raise InterpreterException('Must have one or two arguments.')
+ propname = args[0]
+ if not isinstance(propname, str):
+ raise InterpreterException('Property name must be string.')
+ try:
+ props = self.interpreter.environment.cross_info.get_properties()
+ return props[propname]
+ except Exception:
+ if len(args) == 2:
+ return args[1]
+ raise InterpreterException('Unknown cross property: %s.' % propname)
+
class Interpreter():
def __init__(self, build, backend, subproject='', subdir='', subproject_dir='subprojects'):
@@ -1069,7 +1090,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 +1775,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 +1809,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
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index 4b529c7..33874fa 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -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',
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index 3768614..1924b95 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -19,6 +19,14 @@ from glob import glob
from mesonbuild.scripts import depfixer
from mesonbuild.scripts import destdir_join
+install_log_file = None
+
+def append_to_log(line):
+ install_log_file.write(line)
+ if not line.endswith('\n'):
+ install_log_file.write('\n')
+ install_log_file.flush()
+
def do_copy(from_file, to_file):
try:
# Python's copyfile fails if the target file already exists.
@@ -27,6 +35,7 @@ def do_copy(from_file, to_file):
pass
shutil.copyfile(from_file, to_file)
shutil.copystat(from_file, to_file)
+ append_to_log(to_file)
def do_install(datafilename):
ifile = open(datafilename, 'rb')
@@ -78,6 +87,7 @@ def install_subdirs(data):
os.mkdir(parent_dir)
shutil.copystat(os.path.split(abs_src)[0], parent_dir)
shutil.copy2(abs_src, abs_dst, follow_symlinks=False)
+ append_to_log(abs_dst)
def install_data(d):
for i in d.data:
@@ -104,6 +114,7 @@ def install_man(d):
if outfilename.endswith('.gz') and not full_source_filename.endswith('.gz'):
open(outfilename, 'wb').write(gzip.compress(open(full_source_filename, 'rb').read()))
shutil.copystat(full_source_filename, outfilename)
+ append_to_log(outfilename)
else:
do_copy(full_source_filename, outfilename)
@@ -209,6 +220,7 @@ def install_targets(d):
except FileNotFoundError:
pass
os.symlink(os.path.split(fname)[-1], symlinkfilename)
+ append_to_log(symlinkfilename)
except (NotImplementedError, OSError):
if not printed_symlink_error:
print("Symlink creation does not work on this platform.")
@@ -224,11 +236,19 @@ def install_targets(d):
raise
def run(args):
+ global install_log_file
if len(args) != 1:
print('Installer script for Meson. Do not run on your own, mmm\'kay?')
print('meson_install.py [install info file]')
datafilename = args[0]
- do_install(datafilename)
+ private_dir = os.path.split(datafilename)[0]
+ log_dir = os.path.join(private_dir, '../meson-logs')
+ with open(os.path.join(log_dir, 'install-log.txt'), 'w') as lf:
+ install_log_file = lf
+ append_to_log('# List of files installed by Meson')
+ append_to_log('# Does not contain files installed by custom scripts.')
+ do_install(datafilename)
+ install_log_file = None
return 0
if __name__ == '__main__':
diff --git a/test cases/common/58 run target/converter.py b/test cases/common/58 run target/converter.py
new file mode 100644
index 0000000..6acbc84
--- /dev/null
+++ b/test cases/common/58 run target/converter.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+import sys
+
+open(sys.argv[2], 'wb').write(open(sys.argv[1], 'rb').read())
diff --git a/test cases/common/58 run target/fakeburner.py b/test cases/common/58 run target/fakeburner.py
new file mode 100755
index 0000000..a100a6f
--- /dev/null
+++ b/test cases/common/58 run target/fakeburner.py
@@ -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')
diff --git a/test cases/common/58 run target/meson.build b/test cases/common/58 run target/meson.build
index fa25f2a..0febe35 100644
--- a/test cases/common/58 run target/meson.build
+++ b/test cases/common/58 run target/meson.build
@@ -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.")'])
diff --git a/test cases/failing/29 no crossprop/meson.build b/test cases/failing/29 no crossprop/meson.build
new file mode 100644
index 0000000..bd3a743
--- /dev/null
+++ b/test cases/failing/29 no crossprop/meson.build
@@ -0,0 +1,3 @@
+project('no crossprop', 'c')
+
+message(meson.get_cross_property('nonexisting'))