aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci_frameworks.yml18
-rw-r--r--.github/workflows/lint_mypy.yml8
-rw-r--r--.github/workflows/os_comp.yml1
-rw-r--r--docs/markdown/IDE-integration.md6
-rw-r--r--docs/markdown/Reference-manual.md44
-rw-r--r--docs/markdown/snippets/introspect_test_deps.md5
-rw-r--r--mesonbuild/backend/backends.py12
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/environment.py16
-rw-r--r--mesonbuild/mcompile.py2
-rw-r--r--mesonbuild/mdist.py12
-rw-r--r--mesonbuild/minit.py2
-rw-r--r--mesonbuild/mintro.py1
-rw-r--r--mesonbuild/mtest.py2
-rw-r--r--mesonbuild/scripts/scanbuild.py2
-rwxr-xr-xrun_unittests.py18
-rw-r--r--test cases/unit/57 introspection/cp.py5
-rw-r--r--test cases/unit/57 introspection/meson.build7
18 files changed, 107 insertions, 58 deletions
diff --git a/.github/workflows/ci_frameworks.yml b/.github/workflows/ci_frameworks.yml
index 12d41f8..172c12c 100644
--- a/.github/workflows/ci_frameworks.yml
+++ b/.github/workflows/ci_frameworks.yml
@@ -17,14 +17,14 @@ jobs:
scalapackMacOS:
runs-on: macos-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
with:
python-version: '3.x'
- run: python -m pip install -e .
- run: brew install pkg-config ninja gcc openmpi lapack scalapack
- run: meson setup "test cases/frameworks/30 scalapack" build
- - run: ninja -C build
+ - run: meson compile -C build
- uses: actions/upload-artifact@v1
if: failure()
with:
@@ -40,14 +40,14 @@ jobs:
HDF5macos:
runs-on: macos-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
with:
python-version: '3.x'
- run: python -m pip install -e .
- run: brew install pkg-config ninja gcc hdf5
- run: meson setup "test cases/frameworks/25 hdf5" build
- - run: ninja -C build
+ - run: meson compile -C build
- uses: actions/upload-artifact@v1
if: failure()
with:
@@ -63,8 +63,8 @@ jobs:
Qt4macos:
runs-on: macos-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
with:
python-version: '3.x'
- run: python -m pip install -e .
@@ -72,7 +72,7 @@ jobs:
- run: brew tap cartr/qt4
- run: brew install qt@4
- run: meson setup "test cases/frameworks/4 qt" build -Drequired=qt4
- - run: ninja -C build
+ - run: meson compile -C build
- uses: actions/upload-artifact@v1
if: failure()
with:
diff --git a/.github/workflows/lint_mypy.yml b/.github/workflows/lint_mypy.yml
index 056f96e..e1615c2 100644
--- a/.github/workflows/lint_mypy.yml
+++ b/.github/workflows/lint_mypy.yml
@@ -15,8 +15,8 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
with:
python-version: '3.x'
# pylint version constraint can be removed when https://github.com/PyCQA/pylint/issues/3524 is resolved
@@ -26,8 +26,8 @@ jobs:
mypy:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
with:
python-version: '3.x'
- run: python -m pip install mypy
diff --git a/.github/workflows/os_comp.yml b/.github/workflows/os_comp.yml
index a5abf7d..3b38bab 100644
--- a/.github/workflows/os_comp.yml
+++ b/.github/workflows/os_comp.yml
@@ -25,7 +25,6 @@ jobs:
- name: Run tests
run: LD_LIBRARY_PATH=/usr/local/share/boost/1.69.0/lib/:$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH python3 run_tests.py
env:
- CI: '1'
XENIAL: '1'
arch:
diff --git a/docs/markdown/IDE-integration.md b/docs/markdown/IDE-integration.md
index 816225f..5188359 100644
--- a/docs/markdown/IDE-integration.md
+++ b/docs/markdown/IDE-integration.md
@@ -247,6 +247,7 @@ line arguments, environment variable settings and how to process the output.
"is_parallel": true / false,
"protocol": "exitcode" / "tap",
"cmd": ["command", "to", "run"],
+ "depends": ["target1-id", "target2-id"],
"env": {
"VARIABLE1": "value 1",
"VARIABLE2": "value 2"
@@ -254,6 +255,11 @@ line arguments, environment variable settings and how to process the output.
}
```
+The `depends` entry *(since 0.56.0)* contains target ids; they can be
+looked up in the targets introspection data. The executable
+pointed to by `cmd` is also included in the entry, as are any
+arguments to the test that are build products.
+
## Build system files
It is also possible to get Meson build files used in your current project. This
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index a860f85..fafc9cb 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1776,7 +1776,7 @@ the following methods.
`MESONINTROSPECT` contains the path to the introspect command that
corresponds to the `meson` executable that was used to configure the
- build. (This might be a different path then the first executable
+ build. (This might be a different path than the first executable
found in `PATH`.) It can be used to query build configuration. Note
that the value will contain many parts, f.ex., it may be `python3
/path/to/meson.py introspect`. The user is responsible for splitting
@@ -2155,27 +2155,27 @@ the following methods:
`args` keyword, you can specify external dependencies to use with
`dependencies` keyword argument.
-- `check_header` *(since 0.47.0)*: returns true if the specified header is *usable* with
- the specified prefix, dependencies, and arguments.
- You can specify external dependencies to use with `dependencies`
- keyword argument and extra code to put above the header test with
- the `prefix` keyword. In order to look for headers in a specific
- directory you can use `args : '-I/extra/include/dir`, but this
- should only be used in exceptional cases for includes that can't be
- detected via pkg-config and passed via `dependencies`. *(since 0.50.0)* The
- `required` keyword argument can be used to abort if the header cannot be
- found.
-
-- `has_header`: returns true if the specified header *exists*, and is
- faster than `check_header()` since it only does a pre-processor check.
- You can specify external dependencies to use with `dependencies`
- keyword argument and extra code to put above the header test with
- the `prefix` keyword. In order to look for headers in a specific
- directory you can use `args : '-I/extra/include/dir`, but this
- should only be used in exceptional cases for includes that can't be
- detected via pkg-config and passed via `dependencies`. *(since 0.50.0)* The
- `required` keyword argument can be used to abort if the header cannot be
- found.
+- `check_header(header_name)` *(since 0.47.0)*: returns true if the
+ specified header is *usable* with the specified prefix,
+ dependencies, and arguments. You can specify external dependencies
+ to use with `dependencies` keyword argument and extra code to put
+ above the header test with the `prefix` keyword. In order to look
+ for headers in a specific directory you can use `args :
+ '-I/extra/include/dir`, but this should only be used in exceptional
+ cases for includes that can't be detected via pkg-config and passed
+ via `dependencies`. *(since 0.50.0)* The `required` keyword argument
+ can be used to abort if the header cannot be found.
+
+- `has_header(header_name)`: returns true if the specified header
+ *exists*, and is faster than `check_header()` since it only does a
+ pre-processor check. You can specify external dependencies to use
+ with `dependencies` keyword argument and extra code to put above the
+ header test with the `prefix` keyword. In order to look for headers
+ in a specific directory you can use `args : '-I/extra/include/dir`,
+ but this should only be used in exceptional cases for includes that
+ can't be detected via pkg-config and passed via `dependencies`.
+ *(since 0.50.0)* The `required` keyword argument can be used to
+ abort if the header cannot be found.
- `has_header_symbol(headername, symbolname)`: detects
whether a particular symbol (function, variable, #define, type
diff --git a/docs/markdown/snippets/introspect_test_deps.md b/docs/markdown/snippets/introspect_test_deps.md
new file mode 100644
index 0000000..a29ea09
--- /dev/null
+++ b/docs/markdown/snippets/introspect_test_deps.md
@@ -0,0 +1,5 @@
+## Dependencies listed in test and benchmark introspection
+
+The introspection data for tests and benchmarks now includes the target
+ids for executables and built files that are needed by the test. IDEs can
+use this feature to update the build more quickly before running a test.
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 7bdccbf..6c5b75a 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -120,7 +120,8 @@ class TestSerialisation:
env: build.EnvironmentVariables, should_fail: bool,
timeout: T.Optional[int], workdir: T.Optional[str],
extra_paths: T.List[str], protocol: TestProtocol, priority: int,
- cmd_is_built: bool):
+ cmd_is_built: bool,
+ depends: T.List[str]):
self.name = name
self.project_name = project
self.suite = suite
@@ -140,6 +141,7 @@ class TestSerialisation:
self.priority = priority
self.needs_exe_wrapper = needs_exe_wrapper
self.cmd_is_built = cmd_is_built
+ self.depends = depends
def get_backend_from_name(backend: str, build: T.Optional[build.Build] = None, interpreter: T.Optional['Interpreter'] = None) -> T.Optional['Backend']:
@@ -830,7 +832,12 @@ class Backend:
extra_paths = []
cmd_args = []
+ depends = set(t.depends)
+ if isinstance(exe, build.Target):
+ depends.add(exe)
for a in unholder(t.cmd_args):
+ if isinstance(a, build.Target):
+ depends.add(a)
if isinstance(a, build.BuildTarget):
extra_paths += self.determine_windows_extra_paths(a, [])
if isinstance(a, mesonlib.File):
@@ -852,7 +859,8 @@ class Backend:
t.is_parallel, cmd_args, t.env,
t.should_fail, t.timeout, t.workdir,
extra_paths, t.protocol, t.priority,
- isinstance(exe, build.Executable))
+ isinstance(exe, build.Executable),
+ [x.get_id() for x in depends])
arr.append(ts)
return arr
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 2d0a0b9..9004165 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -548,7 +548,7 @@ int dummy;
rules += ["%s%s" % (rule, ext) for rule in [self.get_pch_rule_name(lang, for_machine)]
for ext in ['', '_RSP']]
compdb_options = ['-x'] if mesonlib.version_compare(self.ninja_version, '>=1.9') else []
- ninja_compdb = [self.ninja_command, '-t', 'compdb'] + compdb_options + rules
+ ninja_compdb = self.ninja_command + ['-t', 'compdb'] + compdb_options + rules
builddir = self.environment.get_build_dir()
try:
jsondb = subprocess.check_output(ninja_compdb, cwd=builddir)
@@ -2958,7 +2958,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.add_build(elem)
elem = NinjaBuildElement(self.all_outputs, 'meson-clean', 'CUSTOM_COMMAND', 'PHONY')
- elem.add_item('COMMAND', [self.ninja_command, '-t', 'clean'])
+ elem.add_item('COMMAND', self.ninja_command + ['-t', 'clean'])
elem.add_item('description', 'Cleaning')
# Alias that runs the above-defined meson-clean target
self.create_target_alias('meson-clean')
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 5600f9d..f8282c0 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -168,15 +168,19 @@ def find_coverage_tools():
return gcovr_exe, gcovr_new_rootdir, lcov_exe, genhtml_exe, llvm_cov_exe
-def detect_ninja(version: str = '1.7', log: bool = False) -> str:
+def detect_ninja(version: str = '1.7', log: bool = False) -> T.List[str]:
r = detect_ninja_command_and_version(version, log)
return r[0] if r else None
-def detect_ninja_command_and_version(version: str = '1.7', log: bool = False) -> (str, str):
+def detect_ninja_command_and_version(version: str = '1.7', log: bool = False) -> (T.List[str], str):
+ from .dependencies.base import ExternalProgram
env_ninja = os.environ.get('NINJA', None)
for n in [env_ninja] if env_ninja else ['ninja', 'ninja-build', 'samu']:
+ prog = ExternalProgram(n, silent=True)
+ if not prog.found():
+ continue
try:
- p, found = Popen_safe([n, '--version'])[0:2]
+ p, found = Popen_safe(prog.command + ['--version'])[0:2]
except (FileNotFoundError, PermissionError):
# Doesn't exist in PATH or isn't executable
continue
@@ -184,7 +188,6 @@ def detect_ninja_command_and_version(version: str = '1.7', log: bool = False) ->
# Perhaps we should add a way for the caller to know the failure mode
# (not found or too old)
if p.returncode == 0 and mesonlib.version_compare(found, '>=' + version):
- n = shutil.which(n)
if log:
name = os.path.basename(n)
if name.endswith('-' + found):
@@ -193,8 +196,9 @@ def detect_ninja_command_and_version(version: str = '1.7', log: bool = False) ->
name = 'ninja'
if name == 'samu':
name = 'samurai'
- mlog.log('Found {}-{} at {}'.format(name, found, quote_arg(n)))
- return (n, found)
+ mlog.log('Found {}-{} at {}'.format(name, found,
+ ' '.join([quote_arg(x) for x in prog.command])))
+ return (prog.command, found)
def get_llvm_tool_names(tool: str) -> T.List[str]:
# Ordered list of possible suffixes of LLVM executables to try. Start with
diff --git a/mesonbuild/mcompile.py b/mesonbuild/mcompile.py
index 3199f59..8e2a38f 100644
--- a/mesonbuild/mcompile.py
+++ b/mesonbuild/mcompile.py
@@ -139,7 +139,7 @@ def get_parsed_args_ninja(options: 'argparse.Namespace', builddir: Path) -> T.Li
raise MesonException('Cannot find ninja.')
mlog.log('Found runner:', runner)
- cmd = [runner, '-C', builddir.as_posix()]
+ cmd = runner + ['-C', builddir.as_posix()]
if options.targets:
intro_data = parse_introspect_data(builddir)
diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py
index 9d94ace..fbda240 100644
--- a/mesonbuild/mdist.py
+++ b/mesonbuild/mdist.py
@@ -180,19 +180,19 @@ def create_dist_hg(dist_name, archives, src_root, bld_root, dist_sub, dist_scrip
output_names.append(zipname)
return output_names
-def run_dist_steps(meson_command, unpacked_src_dir, builddir, installdir, ninja_bin):
+def run_dist_steps(meson_command, unpacked_src_dir, builddir, installdir, ninja_args):
if subprocess.call(meson_command + ['--backend=ninja', unpacked_src_dir, builddir]) != 0:
print('Running Meson on distribution package failed')
return 1
- if subprocess.call([ninja_bin], cwd=builddir) != 0:
+ if subprocess.call(ninja_args, cwd=builddir) != 0:
print('Compiling the distribution package failed')
return 1
- if subprocess.call([ninja_bin, 'test'], cwd=builddir) != 0:
+ if subprocess.call(ninja_args + ['test'], cwd=builddir) != 0:
print('Running unit tests on the distribution package failed')
return 1
myenv = os.environ.copy()
myenv['DESTDIR'] = installdir
- if subprocess.call([ninja_bin, 'install'], cwd=builddir, env=myenv) != 0:
+ if subprocess.call(ninja_args + ['install'], cwd=builddir, env=myenv) != 0:
print('Installing the distribution package failed')
return 1
return 0
@@ -206,7 +206,7 @@ def check_dist(packagename, meson_command, extra_meson_args, bld_root, privdir):
if os.path.exists(p):
windows_proof_rmtree(p)
os.mkdir(p)
- ninja_bin = detect_ninja()
+ ninja_args = detect_ninja()
shutil.unpack_archive(packagename, unpackdir)
unpacked_files = glob(os.path.join(unpackdir, '*'))
assert(len(unpacked_files) == 1)
@@ -216,7 +216,7 @@ def check_dist(packagename, meson_command, extra_meson_args, bld_root, privdir):
if o['name'] not in ['backend', 'install_umask', 'buildtype']]
meson_command += extra_meson_args
- ret = run_dist_steps(meson_command, unpacked_src_dir, builddir, installdir, ninja_bin)
+ ret = run_dist_steps(meson_command, unpacked_src_dir, builddir, installdir, ninja_args)
if ret > 0:
print('Dist check build directory was {}'.format(builddir))
else:
diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py
index d0aff49..06e6dd4 100644
--- a/mesonbuild/minit.py
+++ b/mesonbuild/minit.py
@@ -174,7 +174,7 @@ def run(options) -> int:
ret = subprocess.run(cmd)
if ret.returncode:
raise SystemExit
- cmd = [detect_ninja(), '-C', options.builddir]
+ cmd = detect_ninja() + ['-C', options.builddir]
ret = subprocess.run(cmd)
if ret.returncode:
raise SystemExit
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 0049bbd..d55227a 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -325,6 +325,7 @@ def get_test_list(testdata) -> T.List[T.Dict[str, T.Union[str, int, T.List[str],
to['is_parallel'] = t.is_parallel
to['priority'] = t.priority
to['protocol'] = str(t.protocol)
+ to['depends'] = t.depends
result.append(to)
return result
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index de82234..b9a1176 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -1178,7 +1178,7 @@ def rebuild_all(wd: str) -> bool:
print("Can't find ninja, can't rebuild test.")
return False
- ret = subprocess.run([ninja, '-C', wd]).returncode
+ ret = subprocess.run(ninja + ['-C', wd]).returncode
if ret != 0:
print('Could not rebuild {}'.format(wd))
return False
diff --git a/mesonbuild/scripts/scanbuild.py b/mesonbuild/scripts/scanbuild.py
index b9e96d2..0190067 100644
--- a/mesonbuild/scripts/scanbuild.py
+++ b/mesonbuild/scripts/scanbuild.py
@@ -22,7 +22,7 @@ from ..environment import detect_ninja, detect_scanbuild
def scanbuild(exelist, srcdir, blddir, privdir, logdir, args):
with tempfile.TemporaryDirectory(dir=privdir) as scandir:
meson_cmd = exelist + args
- build_cmd = exelist + ['-o', logdir, detect_ninja(), '-C', scandir]
+ build_cmd = exelist + ['-o', logdir] + detect_ninja() + ['-C', scandir]
rc = subprocess.call(meson_cmd + [srcdir, scandir])
if rc != 0:
return rc
diff --git a/run_unittests.py b/run_unittests.py
index 8c03693..2ff2af5 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -4281,6 +4281,7 @@ recommended as it is not supported on some platforms''')
('suite', list),
('is_parallel', bool),
('protocol', str),
+ ('depends', list),
]
buildoptions_keylist = [
@@ -4338,12 +4339,28 @@ recommended as it is not supported on some platforms''')
assertKeyTypes(root_keylist, res)
+ # Match target ids to input and output files for ease of reference
+ src_to_id = {}
+ out_to_id = {}
+ for i in res['targets']:
+ print(json.dump(i, sys.stdout))
+ out_to_id.update({os.path.relpath(out, self.builddir): i['id']
+ for out in i['filename']})
+ for group in i['target_sources']:
+ src_to_id.update({os.path.relpath(src, testdir): i['id']
+ for src in group['sources']})
+
# Check Tests and benchmarks
tests_to_find = ['test case 1', 'test case 2', 'benchmark 1']
+ deps_to_find = {'test case 1': [src_to_id['t1.cpp']],
+ 'test case 2': [src_to_id['t2.cpp'], src_to_id['t3.cpp']],
+ 'benchmark 1': [out_to_id['file2'], src_to_id['t3.cpp']]}
for i in res['benchmarks'] + res['tests']:
assertKeyTypes(test_keylist, i)
if i['name'] in tests_to_find:
tests_to_find.remove(i['name'])
+ self.assertEqual(sorted(i['depends']),
+ sorted(deps_to_find[i['name']]))
self.assertListEqual(tests_to_find, [])
# Check buildoptions
@@ -4484,6 +4501,7 @@ recommended as it is not supported on some platforms''')
res_nb = self.introspect_directory(testfile, ['--targets'] + self.meson_args)
# Account for differences in output
+ res_wb = [i for i in res_wb if i['type'] != 'custom']
for i in res_wb:
i['filename'] = [os.path.relpath(x, self.builddir) for x in i['filename']]
if 'install_filename' in i:
diff --git a/test cases/unit/57 introspection/cp.py b/test cases/unit/57 introspection/cp.py
new file mode 100644
index 0000000..cb09cf3
--- /dev/null
+++ b/test cases/unit/57 introspection/cp.py
@@ -0,0 +1,5 @@
+#! /usr/bin/env python3
+
+import sys
+from shutil import copyfile
+copyfile(*sys.argv[1:])
diff --git a/test cases/unit/57 introspection/meson.build b/test cases/unit/57 introspection/meson.build
index 5d4dd02..3a3db10 100644
--- a/test cases/unit/57 introspection/meson.build
+++ b/test cases/unit/57 introspection/meson.build
@@ -26,6 +26,9 @@ var1 = '1'
var2 = 2.to_string()
var3 = 'test3'
+cus = custom_target('custom target test', output: 'file2', input: 'cp.py',
+ command: [find_program('cp.py'), '@INPUT@', '@OUTPUT@'])
+
t1 = executable('test' + var1, ['t1.cpp'], link_with: [sharedlib], install: not false, build_by_default: get_option('test_opt2'))
t2 = executable('test@0@'.format('@0@'.format(var2)), sources: ['t2.cpp'], link_with: [staticlib])
t3 = executable(var3, 't3.cpp', link_with: [sharedlib, staticlib], dependencies: [dep1])
@@ -44,8 +47,8 @@ osmesa_lib_name = osmesa_lib_name + osmesa_bits
message(osmesa_lib_name) # Infinite recursion gets triggered here when the parameter osmesa_lib_name is resolved
test('test case 1', t1)
-test('test case 2', t2)
-benchmark('benchmark 1', t3)
+test('test case 2', t2, depends: t3)
+benchmark('benchmark 1', t3, args: cus)
### Stuff to test the AST JSON printer
foreach x : ['a', 'b', 'c']