aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py103
-rw-r--r--mesonbuild/compilers/fortran.py6
-rw-r--r--mesonbuild/interpreter.py7
-rwxr-xr-xrun_unittests.py55
-rw-r--r--test cases/common/159 reserved targets/PHONY/meson.build1
-rw-r--r--test cases/common/159 reserved targets/all/meson.build1
-rw-r--r--test cases/common/159 reserved targets/benchmark/meson.build1
-rw-r--r--test cases/common/159 reserved targets/clean-ctlist/meson.build1
-rw-r--r--test cases/common/159 reserved targets/clean-gcda/meson.build1
-rw-r--r--test cases/common/159 reserved targets/clean-gcno/meson.build1
-rw-r--r--test cases/common/159 reserved targets/clean/meson.build1
-rw-r--r--test cases/common/159 reserved targets/coverage-html/meson.build1
-rw-r--r--test cases/common/159 reserved targets/coverage-text/meson.build1
-rw-r--r--test cases/common/159 reserved targets/coverage-xml/meson.build1
-rw-r--r--test cases/common/159 reserved targets/coverage/meson.build1
-rw-r--r--test cases/common/159 reserved targets/dist/meson.build1
-rw-r--r--test cases/common/159 reserved targets/distcheck/meson.build1
-rw-r--r--test cases/common/159 reserved targets/install/meson.build1
-rw-r--r--test cases/common/159 reserved targets/meson.build32
-rw-r--r--test cases/common/159 reserved targets/phony/meson.build1
-rw-r--r--test cases/common/159 reserved targets/reconfigure/meson.build1
-rw-r--r--test cases/common/159 reserved targets/runtarget/meson.build2
-rw-r--r--test cases/common/159 reserved targets/scan-build/meson.build1
-rw-r--r--test cases/common/159 reserved targets/test.c3
-rw-r--r--test cases/common/159 reserved targets/test/meson.build1
-rw-r--r--test cases/common/159 reserved targets/uninstall/meson.build1
26 files changed, 179 insertions, 48 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 6b0c533..0587cff 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -138,13 +138,28 @@ class NinjaBackend(backends.Backend):
self.fortran_deps = {}
self.all_outputs = {}
+ def create_target_alias(self, to_target, outfile):
+ # We need to use aliases for targets that might be used as directory
+ # names to workaround a Ninja bug that breaks `ninja -t clean`.
+ # This is used for 'reserved' targets such as 'test', 'install',
+ # 'benchmark', etc, and also for RunTargets.
+ # https://github.com/mesonbuild/meson/issues/1644
+ if not to_target.startswith('meson-'):
+ m = 'Invalid usage of create_target_alias with {!r}'
+ raise AssertionError(m.format(to_target))
+ from_target = to_target[len('meson-'):]
+ elem = NinjaBuildElement(self.all_outputs, from_target, 'phony', to_target)
+ elem.write(outfile)
+
def detect_vs_dep_prefix(self, tempfilename):
'''VS writes its dependency in a locale dependent format.
Detect the search prefix to use.'''
- # Of course there is another program called 'cl' on
- # some platforms. Let's just require that on Windows
- # cl points to msvc.
- if not mesonlib.is_windows() or shutil.which('cl') is None:
+ for compiler in self.build.compilers.values():
+ # Have to detect the dependency format
+ if compiler.id == 'msvc':
+ break
+ else:
+ # None of our compilers are MSVC, we're done.
return open(tempfilename, 'a')
filename = os.path.join(self.environment.get_scratch_dir(),
'incdetect.c')
@@ -537,7 +552,7 @@ int dummy;
arg_strings.append(os.path.join(self.environment.get_build_dir(), relfname))
else:
raise AssertionError('Unreachable code in generate_run_target: ' + str(i))
- elem = NinjaBuildElement(self.all_outputs, target.name, 'CUSTOM_COMMAND', [])
+ elem = NinjaBuildElement(self.all_outputs, 'meson-' + target.name, 'CUSTOM_COMMAND', [])
cmd += [self.environment.get_source_dir(),
self.environment.get_build_dir(),
target.subdir,
@@ -573,10 +588,12 @@ int dummy;
elem.add_item('description', 'Running external command %s.' % target.name)
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the target defined above with the name the user specified
+ self.create_target_alias('meson-' + target.name, outfile)
self.processed_targets[target.name + target.type_suffix()] = True
def generate_coverage_rules(self, outfile):
- e = NinjaBuildElement(self.all_outputs, 'coverage', 'CUSTOM_COMMAND', 'PHONY')
+ e = NinjaBuildElement(self.all_outputs, 'meson-coverage', 'CUSTOM_COMMAND', 'PHONY')
e.add_item('COMMAND', [sys.executable,
self.environment.get_build_command(),
'--internal', 'coverage',
@@ -585,6 +602,8 @@ int dummy;
self.environment.get_log_dir()])
e.add_item('description', 'Generates coverage reports.')
e.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage', outfile)
self.generate_coverage_legacy_rules(outfile)
def generate_coverage_legacy_rules(self, outfile):
@@ -592,22 +611,28 @@ int dummy;
added_rule = False
if gcovr_exe:
added_rule = True
- elem = NinjaBuildElement(self.all_outputs, 'coverage-xml', 'CUSTOM_COMMAND', '')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-xml', 'CUSTOM_COMMAND', '')
elem.add_item('COMMAND', [gcovr_exe, '-x', '-r', self.environment.get_source_dir(),
'-o', os.path.join(self.environment.get_log_dir(), 'coverage.xml')])
elem.add_item('DESC', 'Generating XML coverage report.')
elem.write(outfile)
- elem = NinjaBuildElement(self.all_outputs, 'coverage-text', 'CUSTOM_COMMAND', '')
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-xml', outfile)
+ elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-text', 'CUSTOM_COMMAND', '')
elem.add_item('COMMAND', [gcovr_exe, '-r', self.environment.get_source_dir(),
'-o', os.path.join(self.environment.get_log_dir(), 'coverage.txt')])
elem.add_item('DESC', 'Generating text coverage report.')
elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-text', outfile)
if lcov_exe and genhtml_exe:
added_rule = True
htmloutdir = os.path.join(self.environment.get_log_dir(), 'coveragereport')
covinfo = os.path.join(self.environment.get_log_dir(), 'coverage.info')
phony_elem = NinjaBuildElement(self.all_outputs, 'coverage-html', 'phony', os.path.join(htmloutdir, 'index.html'))
phony_elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-html', outfile)
elem = NinjaBuildElement(self.all_outputs, os.path.join(htmloutdir, 'index.html'), 'CUSTOM_COMMAND', '')
command = [lcov_exe, '--directory', self.environment.get_build_dir(),
'--capture', '--output-file', covinfo, '--no-checksum',
@@ -636,7 +661,7 @@ int dummy;
self.environment.get_prefix(),
strip_bin,
get_meson_script(self.environment, 'mesonintrospect'))
- elem = NinjaBuildElement(self.all_outputs, 'install', 'CUSTOM_COMMAND', 'PHONY')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-install', 'CUSTOM_COMMAND', 'PHONY')
elem.add_dep('all')
elem.add_item('DESC', 'Installing files.')
elem.add_item('COMMAND', [sys.executable, self.environment.get_build_command(), '--internal', 'install', install_data_file])
@@ -649,6 +674,8 @@ int dummy;
self.generate_custom_install_script(d)
self.generate_subdir_install(d)
elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-install', outfile)
with open(install_data_file, 'wb') as ofile:
pickle.dump(d, ofile)
@@ -822,20 +849,24 @@ int dummy;
cmd += ['--no-stdsplit']
if self.environment.coredata.get_builtin_option('errorlogs'):
cmd += ['--print-errorlogs']
- elem = NinjaBuildElement(self.all_outputs, 'test', 'CUSTOM_COMMAND', ['all', 'PHONY'])
+ elem = NinjaBuildElement(self.all_outputs, 'meson-test', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd)
elem.add_item('DESC', 'Running all tests.')
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the above-defined meson-test target
+ self.create_target_alias('meson-test', outfile)
# And then benchmarks.
cmd = [sys.executable, '-u', self.environment.get_build_command(), 'test', '--benchmark', '--logbase',
'benchmarklog', '--num-processes=1', '--no-rebuild']
- elem = NinjaBuildElement(self.all_outputs, 'benchmark', 'CUSTOM_COMMAND', ['all', 'PHONY'])
+ elem = NinjaBuildElement(self.all_outputs, 'meson-benchmark', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd)
elem.add_item('DESC', 'Running benchmark suite.')
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the above-defined meson-benchmark target
+ self.create_target_alias('meson-benchmark', outfile)
def generate_rules(self, outfile):
outfile.write('# Rules for compiling.\n\n')
@@ -2453,7 +2484,7 @@ rule FORTRAN_DEP_HACK
mlog.debug("Library versioning disabled because we do not have symlink creation privileges.")
def generate_custom_target_clean(self, outfile, trees):
- e = NinjaBuildElement(self.all_outputs, 'clean-ctlist', 'CUSTOM_COMMAND', 'PHONY')
+ e = NinjaBuildElement(self.all_outputs, 'meson-clean-ctlist', 'CUSTOM_COMMAND', 'PHONY')
d = CleanTrees(self.environment.get_build_dir(), trees)
d_file = os.path.join(self.environment.get_scratch_dir(), 'cleantrees.dat')
e.add_item('COMMAND', [sys.executable,
@@ -2461,25 +2492,31 @@ rule FORTRAN_DEP_HACK
'--internal', 'cleantrees', d_file])
e.add_item('description', 'Cleaning custom target directories.')
e.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-clean-ctlist', outfile)
# Write out the data file passed to the script
with open(d_file, 'wb') as ofile:
pickle.dump(d, ofile)
return 'clean-ctlist'
def generate_gcov_clean(self, outfile):
- gcno_elem = NinjaBuildElement(self.all_outputs, 'clean-gcno', 'CUSTOM_COMMAND', 'PHONY')
- script_root = self.environment.get_script_dir()
- clean_script = os.path.join(script_root, 'delwithsuffix.py')
- gcno_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcno'])
- gcno_elem.add_item('description', 'Deleting gcno files.')
- gcno_elem.write(outfile)
-
- gcda_elem = NinjaBuildElement(self.all_outputs, 'clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
- script_root = self.environment.get_script_dir()
- clean_script = os.path.join(script_root, 'delwithsuffix.py')
- gcda_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcda'])
- gcda_elem.add_item('description', 'Deleting gcda files.')
- gcda_elem.write(outfile)
+ gcno_elem = NinjaBuildElement(self.all_outputs, 'meson-clean-gcno', 'CUSTOM_COMMAND', 'PHONY')
+ script_root = self.environment.get_script_dir()
+ clean_script = os.path.join(script_root, 'delwithsuffix.py')
+ gcno_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcno'])
+ gcno_elem.add_item('description', 'Deleting gcno files.')
+ gcno_elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-clean-gcno', outfile)
+
+ gcda_elem = NinjaBuildElement(self.all_outputs, 'meson-clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
+ script_root = self.environment.get_script_dir()
+ clean_script = os.path.join(script_root, 'delwithsuffix.py')
+ gcda_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcda'])
+ gcda_elem.add_item('description', 'Deleting gcda files.')
+ gcda_elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-clean-gcda', outfile)
def get_user_option_args(self):
cmds = []
@@ -2491,7 +2528,7 @@ rule FORTRAN_DEP_HACK
return sorted(cmds)
def generate_dist(self, outfile):
- elem = NinjaBuildElement(self.all_outputs, 'dist', 'CUSTOM_COMMAND', 'PHONY')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-dist', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('DESC', 'Creating source packages')
elem.add_item('COMMAND', [sys.executable,
self.environment.get_build_command(),
@@ -2502,22 +2539,28 @@ rule FORTRAN_DEP_HACK
self.environment.get_build_command()])
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-dist', outfile)
# For things like scan-build and other helper tools we might have.
def generate_utils(self, outfile):
cmd = [sys.executable, self.environment.get_build_command(),
'--internal', 'scanbuild', self.environment.source_dir, self.environment.build_dir,
sys.executable, self.environment.get_build_command()] + self.get_user_option_args()
- elem = NinjaBuildElement(self.all_outputs, 'scan-build', 'CUSTOM_COMMAND', 'PHONY')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-scan-build', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-scan-build', outfile)
cmd = [sys.executable, self.environment.get_build_command(),
'--internal', 'uninstall']
- elem = NinjaBuildElement(self.all_outputs, 'uninstall', 'CUSTOM_COMMAND', 'PHONY')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-uninstall', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-uninstall', outfile)
def generate_ending(self, outfile):
targetlist = []
@@ -2535,9 +2578,11 @@ rule FORTRAN_DEP_HACK
ninja_command = environment.detect_ninja()
if ninja_command is None:
raise MesonException('Could not detect Ninja v1.6 or newer')
- elem = NinjaBuildElement(self.all_outputs, 'clean', 'CUSTOM_COMMAND', 'PHONY')
+ elem = NinjaBuildElement(self.all_outputs, 'meson-clean', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', [ninja_command, '-t', 'clean'])
elem.add_item('description', 'Cleaning.')
+ # Alias that runs the above-defined meson-clean target
+ self.create_target_alias('meson-clean', outfile)
# If we have custom targets in this project, add all their outputs to
# the list that is passed to the `cleantrees.py` script. The script
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 49200bb..2957a7c 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -165,6 +165,12 @@ class GnuFortranCompiler(FortranCompiler):
def get_always_args(self):
return ['-pipe']
+ def get_coverage_args(self):
+ return ['--coverage']
+
+ def get_coverage_link_args(self):
+ return ['--coverage']
+
def gen_import_library_args(self, implibname):
"""
The name of the outputted import library
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 40ab1fe..5fa0878 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2744,9 +2744,12 @@ different subdirectory.
def add_target(self, name, tobj):
if name == '':
raise InterpreterException('Target name must not be empty.')
+ if name.startswith('meson-'):
+ raise InvalidArguments("Target names starting with 'meson-' are reserved "
+ "for Meson's internal use. Please rename.")
if name in coredata.forbidden_target_names:
- raise InvalidArguments('Target name "%s" is reserved for Meson\'s internal use. Please rename.'
- % name)
+ raise InvalidArguments("Target name '%s' is reserved for Meson's "
+ "internal use. Please rename." % name)
# To permit an executable and a shared library to have the
# same name, such as "foo.exe" and "libfoo.a".
idname = tobj.get_id()
diff --git a/run_unittests.py b/run_unittests.py
index 06b3f4c..b889c3d 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -30,6 +30,7 @@ import mesonbuild.mlog
import mesonbuild.compilers
import mesonbuild.environment
import mesonbuild.mesonlib
+import mesonbuild.coredata
from mesonbuild.mesonlib import is_linux, is_windows, is_osx, is_cygwin, windows_proof_rmtree
from mesonbuild.environment import Environment
from mesonbuild.dependencies import DependencyException
@@ -467,7 +468,7 @@ class BasePlatformTests(unittest.TestCase):
return output
def init(self, srcdir, extra_args=None, default_args=True, inprocess=False):
- self.assertTrue(os.path.exists(srcdir))
+ self.assertPathExists(srcdir)
if extra_args is None:
extra_args = []
if not isinstance(extra_args, list):
@@ -628,6 +629,14 @@ class BasePlatformTests(unittest.TestCase):
else:
raise RuntimeError('Invalid backend: {!r}'.format(self.backend.name))
+ def assertPathExists(self, path):
+ m = 'Path {!r} should exist'.format(path)
+ self.assertTrue(os.path.exists(path), msg=m)
+
+ def assertPathDoesNotExist(self, path):
+ m = 'Path {!r} should not exist'.format(path)
+ self.assertFalse(os.path.exists(path), msg=m)
+
class AllPlatformTests(BasePlatformTests):
'''
@@ -773,11 +782,11 @@ class AllPlatformTests(BasePlatformTests):
exename = os.path.join(self.installdir, 'usr/bin/prog' + exe_suffix)
testdir = os.path.join(self.common_test_dir, '8 install')
self.init(testdir)
- self.assertFalse(os.path.exists(exename))
+ self.assertPathDoesNotExist(exename)
self.install()
- self.assertTrue(os.path.exists(exename))
+ self.assertPathExists(exename)
self.uninstall()
- self.assertFalse(os.path.exists(exename))
+ self.assertPathDoesNotExist(exename)
def test_testsetups(self):
if not shutil.which('valgrind'):
@@ -868,10 +877,10 @@ class AllPlatformTests(BasePlatformTests):
self.build()
genfile = os.path.join(self.builddir, 'generated.dat')
exe = os.path.join(self.builddir, 'fooprog' + exe_suffix)
- self.assertTrue(os.path.exists(genfile))
- self.assertFalse(os.path.exists(exe))
+ self.assertPathExists(genfile)
+ self.assertPathDoesNotExist(exe)
self.build(target=('fooprog' + exe_suffix))
- self.assertTrue(os.path.exists(exe))
+ self.assertPathExists(exe)
def test_internal_include_order(self):
testdir = os.path.join(self.common_test_dir, '138 include order')
@@ -1240,8 +1249,8 @@ int main(int argc, char **argv) {
self.build('dist')
distfile = os.path.join(self.distdir, 'disttest-1.4.3.tar.xz')
checksumfile = distfile + '.sha256sum'
- self.assertTrue(os.path.exists(distfile))
- self.assertTrue(os.path.exists(checksumfile))
+ self.assertPathExists(distfile)
+ self.assertPathExists(checksumfile)
def test_rpath_uses_ORIGIN(self):
'''
@@ -1270,6 +1279,18 @@ int main(int argc, char **argv) {
'/D FOO /D BAR' in cmd or
'"/D" "FOO" "/D" "BAR"' in cmd)
+ def test_all_forbidden_targets_tested(self):
+ '''
+ Test that all forbidden targets are tested in the '159 reserved targets'
+ test. Needs to be a unit test because it accesses Meson internals.
+ '''
+ testdir = os.path.join(self.common_test_dir, '159 reserved targets')
+ targets = mesonbuild.coredata.forbidden_target_names
+ # We don't actually define a target with this name
+ targets.pop('build.ninja')
+ for i in targets:
+ self.assertPathExists(os.path.join(testdir, i))
+
class FailureTests(BasePlatformTests):
'''
@@ -1604,35 +1625,35 @@ class LinuxlikeTests(BasePlatformTests):
# File without aliases set.
nover = os.path.join(libpath, 'libnover.so')
- self.assertTrue(os.path.exists(nover))
+ self.assertPathExists(nover)
self.assertFalse(os.path.islink(nover))
self.assertEqual(get_soname(nover), 'libnover.so')
self.assertEqual(len(glob(nover[:-3] + '*')), 1)
# File with version set
verset = os.path.join(libpath, 'libverset.so')
- self.assertTrue(os.path.exists(verset + '.4.5.6'))
+ self.assertPathExists(verset + '.4.5.6')
self.assertEqual(os.readlink(verset), 'libverset.so.4')
self.assertEqual(get_soname(verset), 'libverset.so.4')
self.assertEqual(len(glob(verset[:-3] + '*')), 3)
# File with soversion set
soverset = os.path.join(libpath, 'libsoverset.so')
- self.assertTrue(os.path.exists(soverset + '.1.2.3'))
+ self.assertPathExists(soverset + '.1.2.3')
self.assertEqual(os.readlink(soverset), 'libsoverset.so.1.2.3')
self.assertEqual(get_soname(soverset), 'libsoverset.so.1.2.3')
self.assertEqual(len(glob(soverset[:-3] + '*')), 2)
# File with version and soversion set to same values
settosame = os.path.join(libpath, 'libsettosame.so')
- self.assertTrue(os.path.exists(settosame + '.7.8.9'))
+ self.assertPathExists(settosame + '.7.8.9')
self.assertEqual(os.readlink(settosame), 'libsettosame.so.7.8.9')
self.assertEqual(get_soname(settosame), 'libsettosame.so.7.8.9')
self.assertEqual(len(glob(settosame[:-3] + '*')), 2)
# File with version and soversion set to different values
bothset = os.path.join(libpath, 'libbothset.so')
- self.assertTrue(os.path.exists(bothset + '.1.2.3'))
+ self.assertPathExists(bothset + '.1.2.3')
self.assertEqual(os.readlink(bothset), 'libbothset.so.1.2.3')
self.assertEqual(os.readlink(bothset + '.1.2.3'), 'libbothset.so.4.5.6')
self.assertEqual(get_soname(bothset), 'libbothset.so.1.2.3')
@@ -1719,9 +1740,9 @@ class LinuxlikeTests(BasePlatformTests):
def test_unity_subproj(self):
testdir = os.path.join(self.common_test_dir, '49 subproject')
self.init(testdir, extra_args='--unity=subprojects')
- self.assertTrue(os.path.exists(os.path.join(self.builddir, 'subprojects/sublib/simpletest@exe/simpletest-unity.c')))
- self.assertTrue(os.path.exists(os.path.join(self.builddir, 'subprojects/sublib/sublib@sha/sublib-unity.c')))
- self.assertFalse(os.path.exists(os.path.join(self.builddir, 'user@exe/user-unity.c')))
+ self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/simpletest@exe/simpletest-unity.c'))
+ self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib/sublib@sha/sublib-unity.c'))
+ self.assertPathDoesNotExist(os.path.join(self.builddir, 'user@exe/user-unity.c'))
self.build()
def test_installed_modes(self):
diff --git a/test cases/common/159 reserved targets/PHONY/meson.build b/test cases/common/159 reserved targets/PHONY/meson.build
new file mode 100644
index 0000000..d25583c
--- /dev/null
+++ b/test cases/common/159 reserved targets/PHONY/meson.build
@@ -0,0 +1 @@
+executable('test-PHONY', '../test.c')
diff --git a/test cases/common/159 reserved targets/all/meson.build b/test cases/common/159 reserved targets/all/meson.build
new file mode 100644
index 0000000..adee882
--- /dev/null
+++ b/test cases/common/159 reserved targets/all/meson.build
@@ -0,0 +1 @@
+executable('test-all', '../test.c')
diff --git a/test cases/common/159 reserved targets/benchmark/meson.build b/test cases/common/159 reserved targets/benchmark/meson.build
new file mode 100644
index 0000000..242cc23
--- /dev/null
+++ b/test cases/common/159 reserved targets/benchmark/meson.build
@@ -0,0 +1 @@
+executable('test-benchmark', '../test.c')
diff --git a/test cases/common/159 reserved targets/clean-ctlist/meson.build b/test cases/common/159 reserved targets/clean-ctlist/meson.build
new file mode 100644
index 0000000..75eb207
--- /dev/null
+++ b/test cases/common/159 reserved targets/clean-ctlist/meson.build
@@ -0,0 +1 @@
+executable('test-clean-ctlist', '../test.c')
diff --git a/test cases/common/159 reserved targets/clean-gcda/meson.build b/test cases/common/159 reserved targets/clean-gcda/meson.build
new file mode 100644
index 0000000..488a527
--- /dev/null
+++ b/test cases/common/159 reserved targets/clean-gcda/meson.build
@@ -0,0 +1 @@
+executable('test-clean-gcda', '../test.c')
diff --git a/test cases/common/159 reserved targets/clean-gcno/meson.build b/test cases/common/159 reserved targets/clean-gcno/meson.build
new file mode 100644
index 0000000..eec789a
--- /dev/null
+++ b/test cases/common/159 reserved targets/clean-gcno/meson.build
@@ -0,0 +1 @@
+executable('test-clean-gcno', '../test.c')
diff --git a/test cases/common/159 reserved targets/clean/meson.build b/test cases/common/159 reserved targets/clean/meson.build
new file mode 100644
index 0000000..4e27b6c
--- /dev/null
+++ b/test cases/common/159 reserved targets/clean/meson.build
@@ -0,0 +1 @@
+executable('test-clean', '../test.c')
diff --git a/test cases/common/159 reserved targets/coverage-html/meson.build b/test cases/common/159 reserved targets/coverage-html/meson.build
new file mode 100644
index 0000000..10a4cc8
--- /dev/null
+++ b/test cases/common/159 reserved targets/coverage-html/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-html', '../test.c')
diff --git a/test cases/common/159 reserved targets/coverage-text/meson.build b/test cases/common/159 reserved targets/coverage-text/meson.build
new file mode 100644
index 0000000..21dcae5
--- /dev/null
+++ b/test cases/common/159 reserved targets/coverage-text/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-text', '../test.c')
diff --git a/test cases/common/159 reserved targets/coverage-xml/meson.build b/test cases/common/159 reserved targets/coverage-xml/meson.build
new file mode 100644
index 0000000..44d7bfb
--- /dev/null
+++ b/test cases/common/159 reserved targets/coverage-xml/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-xml', '../test.c')
diff --git a/test cases/common/159 reserved targets/coverage/meson.build b/test cases/common/159 reserved targets/coverage/meson.build
new file mode 100644
index 0000000..b401055
--- /dev/null
+++ b/test cases/common/159 reserved targets/coverage/meson.build
@@ -0,0 +1 @@
+executable('test-coverage', '../test.c')
diff --git a/test cases/common/159 reserved targets/dist/meson.build b/test cases/common/159 reserved targets/dist/meson.build
new file mode 100644
index 0000000..951bbb4
--- /dev/null
+++ b/test cases/common/159 reserved targets/dist/meson.build
@@ -0,0 +1 @@
+executable('test-dist', '../test.c')
diff --git a/test cases/common/159 reserved targets/distcheck/meson.build b/test cases/common/159 reserved targets/distcheck/meson.build
new file mode 100644
index 0000000..12b9328
--- /dev/null
+++ b/test cases/common/159 reserved targets/distcheck/meson.build
@@ -0,0 +1 @@
+executable('test-distcheck', '../test.c')
diff --git a/test cases/common/159 reserved targets/install/meson.build b/test cases/common/159 reserved targets/install/meson.build
new file mode 100644
index 0000000..4839901
--- /dev/null
+++ b/test cases/common/159 reserved targets/install/meson.build
@@ -0,0 +1 @@
+executable('test-install', '../test.c')
diff --git a/test cases/common/159 reserved targets/meson.build b/test cases/common/159 reserved targets/meson.build
new file mode 100644
index 0000000..5123600
--- /dev/null
+++ b/test cases/common/159 reserved targets/meson.build
@@ -0,0 +1,32 @@
+project('reserved target names', 'c')
+ # FIXME: Setting this causes it to leak to all other tests
+ #default_options : ['b_coverage=true']
+
+subdir('all')
+subdir('benchmark')
+subdir('clean')
+subdir('clean-ctlist')
+subdir('clean-gcda')
+subdir('clean-gcno')
+subdir('coverage')
+subdir('coverage-html')
+subdir('coverage-text')
+subdir('coverage-xml')
+subdir('dist')
+subdir('distcheck')
+subdir('install')
+# We end up creating duplicate lowercase target names for this on
+# case-insensitive HFS+, so disable it
+# https://travis-ci.org/mesonbuild/meson/jobs/264468097
+#subdir('phony')
+subdir('PHONY')
+subdir('reconfigure')
+subdir('scan-build')
+subdir('test')
+subdir('uninstall')
+
+subdir('runtarget')
+
+custom_target('ctlist-test', output : 'out.txt',
+ command : ['echo'], capture : true,
+ build_by_default : true)
diff --git a/test cases/common/159 reserved targets/phony/meson.build b/test cases/common/159 reserved targets/phony/meson.build
new file mode 100644
index 0000000..6710fc1
--- /dev/null
+++ b/test cases/common/159 reserved targets/phony/meson.build
@@ -0,0 +1 @@
+executable('test-phony', '../test.c')
diff --git a/test cases/common/159 reserved targets/reconfigure/meson.build b/test cases/common/159 reserved targets/reconfigure/meson.build
new file mode 100644
index 0000000..c3ea3da
--- /dev/null
+++ b/test cases/common/159 reserved targets/reconfigure/meson.build
@@ -0,0 +1 @@
+executable('test-reconfigure', '../test.c')
diff --git a/test cases/common/159 reserved targets/runtarget/meson.build b/test cases/common/159 reserved targets/runtarget/meson.build
new file mode 100644
index 0000000..52c371b
--- /dev/null
+++ b/test cases/common/159 reserved targets/runtarget/meson.build
@@ -0,0 +1,2 @@
+configure_file(output : 'config.h', configuration: configuration_data())
+run_target('runtarget', command : ['echo'])
diff --git a/test cases/common/159 reserved targets/scan-build/meson.build b/test cases/common/159 reserved targets/scan-build/meson.build
new file mode 100644
index 0000000..1002053
--- /dev/null
+++ b/test cases/common/159 reserved targets/scan-build/meson.build
@@ -0,0 +1 @@
+executable('test-scan-build', '../test.c')
diff --git a/test cases/common/159 reserved targets/test.c b/test cases/common/159 reserved targets/test.c
new file mode 100644
index 0000000..0fb4389
--- /dev/null
+++ b/test cases/common/159 reserved targets/test.c
@@ -0,0 +1,3 @@
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/test cases/common/159 reserved targets/test/meson.build b/test cases/common/159 reserved targets/test/meson.build
new file mode 100644
index 0000000..4ab123c
--- /dev/null
+++ b/test cases/common/159 reserved targets/test/meson.build
@@ -0,0 +1 @@
+executable('test-test', '../test.c')
diff --git a/test cases/common/159 reserved targets/uninstall/meson.build b/test cases/common/159 reserved targets/uninstall/meson.build
new file mode 100644
index 0000000..21c6ca6
--- /dev/null
+++ b/test cases/common/159 reserved targets/uninstall/meson.build
@@ -0,0 +1 @@
+executable('test-uninstall', '../test.c')