diff options
-rw-r--r-- | docs/markdown/Reference-manual.md | 3 | ||||
-rw-r--r-- | docs/markdown/Unit-tests.md | 6 | ||||
-rw-r--r-- | docs/markdown/snippets/add_gdb_path.md | 9 | ||||
-rw-r--r-- | mesonbuild/cmake/interpreter.py | 33 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 2 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 12 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 4 | ||||
-rw-r--r-- | mesonbuild/wrap/wrap.py | 65 | ||||
-rw-r--r-- | test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt | 2 |
10 files changed, 104 insertions, 34 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index c50a611..862c60a 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -155,6 +155,9 @@ run. The behavior of this function is identical to `test` with the exception that there is no `is_parallel` keyword, because benchmarks are never run in parallel. +*Note:* Prior to 0.52.0 benchmark would warn that `depends` and `proiority` +were unsupported, this is incorrect + ### both_libraries() ``` meson diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md index 9c2e3d5..c89d7b0 100644 --- a/docs/markdown/Unit-tests.md +++ b/docs/markdown/Unit-tests.md @@ -157,6 +157,12 @@ $ meson test --gdb --repeat=10000 testname This runs the test up to 10 000 times under GDB automatically. If the program crashes, GDB will halt and the user can debug the application. Note that testing timeouts are disabled in this case so `meson test` will not kill `gdb` while the developer is still debugging it. The downside is that if the test binary freezes, the test runner will wait forever. +Sometimes, the GDB binary is not in the PATH variable or the user wants to use a GDB replacement. Therefore, the invoked GDB program can be specified *(added 0.52.0)*: + +```console +$ meson test --gdb --gdb-path /path/to/gdb testname +``` + ```console $ meson test --print-errorlogs ``` diff --git a/docs/markdown/snippets/add_gdb_path.md b/docs/markdown/snippets/add_gdb_path.md new file mode 100644 index 0000000..873c3fc --- /dev/null +++ b/docs/markdown/snippets/add_gdb_path.md @@ -0,0 +1,9 @@ +## The meson test program now accepts an additional "--gdb-path" argument to specify the GDB binary + +`meson test --gdb testname` invokes GDB with the specific test case. However, sometimes GDB is not in the path or a GDB replacement is wanted. +Therefore, a `--gdb-path` argument was added to specify which binary is executed (per default `gdb`): + +```console +$ meson test --gdb --gdb-path /my/special/location/for/gdb testname +$ meson test --gdb --gdb-path cgdb testname +``` diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 773e2ec..09ac7c6 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -22,7 +22,7 @@ from .traceparser import CMakeTraceParser, CMakeGeneratorTarget from .. import mlog from ..environment import Environment from ..mesonlib import MachineChoice -from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, is_header +from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header from subprocess import Popen, PIPE from typing import Any, List, Dict, Optional, TYPE_CHECKING from threading import Thread @@ -117,6 +117,7 @@ def _generated_file_key(fname: str) -> str: class ConverterTarget: lang_cmake_to_meson = {val.lower(): key for key, val in language_map.items()} + rm_so_version = re.compile(r'(\.[0-9]+)+$') def __init__(self, target: CMakeTarget, env: Environment): self.env = env @@ -211,15 +212,30 @@ class ConverterTarget: mlog.warning('CMake: Target', mlog.bold(self.name), 'not found in CMake trace. This can lead to build errors') # Fix link libraries + def try_resolve_link_with(path: str) -> Optional[str]: + basename = os.path.basename(path) + candidates = [basename, ConverterTarget.rm_so_version.sub('', basename)] + for i in lib_suffixes: + if not basename.endswith('.' + i): + continue + new_basename = basename[:-len(i) - 1] + new_basename = ConverterTarget.rm_so_version.sub('', new_basename) + new_basename = '{}.{}'.format(new_basename, i) + candidates += [new_basename] + for i in candidates: + if i in output_target_map: + return output_target_map[i] + return None + temp = [] for i in self.link_libraries: # Let meson handle this arcane magic if ',-rpath,' in i: continue if not os.path.isabs(i): - basename = os.path.basename(i) - if basename in output_target_map: - self.link_with += [output_target_map[basename]] + link_with = try_resolve_link_with(i) + if link_with: + self.link_with += [link_with] continue temp += [i] @@ -586,14 +602,9 @@ class CMakeInterpreter: # generate the output_target_map output_target_map = {} + output_target_map.update({x.full_name: x for x in self.targets}) + output_target_map.update({_target_key(x.name): x for x in self.targets}) for i in self.targets: - output_target_map[i.full_name] = i - output_target_map[_target_key(i.name)] = i - ttarget = self.trace.targets.get(i.name) - soversion = ttarget.properties.get('SOVERSION') if ttarget else None - if soversion: - k = '{}.{}'.format(i.full_name, soversion[0]) - output_target_map[k] = i for j in i.artifacts: output_target_map[os.path.basename(j)] = i for i in self.custom_targets: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 5fb58ac..ac74fc3 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -39,7 +39,7 @@ Also add corresponding autodetection code in environment.py.""" header_suffixes = ('h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di') obj_suffixes = ('o', 'obj', 'res') -lib_suffixes = ('a', 'lib', 'dll', 'dylib', 'so') +lib_suffixes = ('a', 'lib', 'dll', 'dll.a', 'dylib', 'so') # Mapping of language to suffixes of files that should always be in that language # This means we can't include .h headers here since they could be C, C++, ObjC, etc. lang_suffixes = { diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index eae5a16..1d76a1d 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1967,13 +1967,15 @@ known_build_target_kwargs = ( {'target_type'} ) +_base_test_args = {'args', 'depends', 'env', 'should_fail', 'timeout', 'workdir', 'suite', 'priority', 'protocol'} + permitted_kwargs = {'add_global_arguments': {'language', 'native'}, 'add_global_link_arguments': {'language', 'native'}, 'add_languages': {'required'}, 'add_project_link_arguments': {'language', 'native'}, 'add_project_arguments': {'language', 'native'}, 'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env', 'is_default'}, - 'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'}, + 'benchmark': _base_test_args, 'build_target': known_build_target_kwargs, 'configure_file': {'input', 'output', @@ -2052,8 +2054,7 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'}, 'library': known_library_kwargs, 'subdir': {'if_found'}, 'subproject': {'version', 'default_options', 'required'}, - 'test': {'args', 'depends', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', - 'suite', 'protocol', 'priority'}, + 'test': set.union(_base_test_args, {'is_parallel'}), 'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'}, } @@ -3385,8 +3386,13 @@ This will become a hard error in the future.''' % kwargs['input'], location=self self.generators.append(gen) return gen + @FeatureNewKwargs('benchmark', '0.46.0', ['depends']) + @FeatureNewKwargs('benchmark', '0.52.0', ['priority']) @permittedKwargs(permitted_kwargs['benchmark']) def func_benchmark(self, node, args, kwargs): + # is_parallel isn't valid here, so make sure it isn't passed + if 'is_parallel' in kwargs: + del kwargs['is_parallel'] self.add_test(node, args, kwargs, False) @FeatureNewKwargs('test', '0.46.0', ['depends']) diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 7943041..d112d1f 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -85,6 +85,8 @@ def add_arguments(parser: argparse.ArgumentParser) -> None: help='Do not rebuild before running tests.') parser.add_argument('--gdb', default=False, dest='gdb', action='store_true', help='Run test under gdb.') + parser.add_argument('--gdb-path', default='gdb', dest='gdb_path', + help='Path to the gdb binary (default: gdb).') parser.add_argument('--list', default=False, dest='list', action='store_true', help='List available tests.') parser.add_argument('--wrapper', default=None, dest='wrapper', type=split_args, @@ -892,7 +894,7 @@ Timeout: %4d def get_wrapper(options: argparse.Namespace) -> typing.List[str]: wrap = [] # type: typing.List[str] if options.gdb: - wrap = ['gdb', '--quiet', '--nh'] + wrap = [options.gdb_path, '--quiet', '--nh'] if options.repeat > 1: wrap += ['-ex', 'run', '-ex', 'quit'] # Signal the end of arguments to gdb diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 89bc307..8b19b6d 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -226,27 +226,56 @@ class Resolver: self.apply_patch() def get_git(self): - # git doesn't support directly cloning shallowly for commits, - # so we follow https://stackoverflow.com/a/43136160 - subprocess.check_call(['git', 'init', self.directory], cwd=self.subdir_root) - subprocess.check_call(['git', 'remote', 'add', 'origin', self.wrap.get('url')], - cwd=self.dirname) - git_options = [] revno = self.wrap.get('revision') - if self.wrap.values.get('depth', '') != '': - git_options.extend(['--depth', self.wrap.values.get('depth')]) - subprocess.check_call(['git', 'fetch'] + git_options + ['origin', revno], - cwd=self.dirname) - subprocess.check_call(['git', 'checkout', revno], cwd=self.dirname) - if self.wrap.values.get('clone-recursive', '').lower() == 'true': - subprocess.check_call(['git', 'submodule', 'update', - '--init', '--checkout', '--recursive'] + git_options, + is_shallow = self.wrap.values.get('depth', '') != '' + # for some reason git only allows commit ids to be shallowly fetched by fetch not with clone + if is_shallow and self.is_git_full_commit_id(revno): + # git doesn't support directly cloning shallowly for commits, + # so we follow https://stackoverflow.com/a/43136160 + subprocess.check_call(['git', 'init', self.directory], cwd=self.subdir_root) + subprocess.check_call(['git', 'remote', 'add', 'origin', self.wrap.get('url')], cwd=self.dirname) - push_url = self.wrap.values.get('push-url') - if push_url: - subprocess.check_call(['git', 'remote', 'set-url', - '--push', 'origin', push_url], + revno = self.wrap.get('revision') + subprocess.check_call(['git', 'fetch', '--depth', self.wrap.values.get('depth'), 'origin', revno], cwd=self.dirname) + subprocess.check_call(['git', 'checkout', revno], cwd=self.dirname) + if self.wrap.values.get('clone-recursive', '').lower() == 'true': + subprocess.check_call(['git', 'submodule', 'update', + '--init', '--checkout', '--recursive', '--depth', self.wrap.values.get('depth')], + cwd=self.dirname) + push_url = self.wrap.values.get('push-url') + if push_url: + subprocess.check_call(['git', 'remote', 'set-url', + '--push', 'origin', push_url], + cwd=self.dirname) + else: + if not is_shallow: + subprocess.check_call(['git', 'clone', self.wrap.get('url'), + self.directory], cwd=self.subdir_root) + if revno.lower() != 'head': + if subprocess.call(['git', 'checkout', revno], cwd=self.dirname) != 0: + subprocess.check_call(['git', 'fetch', self.wrap.get('url'), revno], cwd=self.dirname) + subprocess.check_call(['git', 'checkout', revno], cwd=self.dirname) + else: + subprocess.check_call(['git', 'clone', '--depth', self.wrap.values.get('depth'), + '--branch', revno, + self.wrap.get('url'), + self.directory], cwd=self.subdir_root) + if self.wrap.values.get('clone-recursive', '').lower() == 'true': + subprocess.check_call(['git', 'submodule', 'update', + '--init', '--checkout', '--recursive', '--depth', self.wrap.values.get('depth')], + cwd=self.dirname) + push_url = self.wrap.values.get('push-url') + if push_url: + subprocess.check_call(['git', 'remote', 'set-url', + '--push', 'origin', push_url], + cwd=self.dirname) + + def is_git_full_commit_id(self, revno): + result = False + if len(revno) in (40, 64): # 40 for sha1, 64 for upcoming sha256 + result = all((ch in '0123456789AaBbCcDdEeFf' for ch in revno)) + return result def get_hg(self): revno = self.wrap.get('revision') diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt index f9e7578..05ccb9e 100644 --- a/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt +++ b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt @@ -14,6 +14,8 @@ add_library(cmModLib SHARED lib/cmMod.cpp) include(GenerateExportHeader) generate_export_header(cmModLib) +set_target_properties(cmModLib PROPERTIES VERSION 1.0.1) + add_executable(testEXE main.cpp) target_link_libraries(cmModLib ZLIB::ZLIB) diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt index 2fdd5a8..2f6267d 100644 --- a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt +++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt @@ -12,6 +12,8 @@ add_library(cmModLib SHARED lib/cmMod.cpp) include(GenerateExportHeader) generate_export_header(cmModLib) +set_target_properties(cmModLib PROPERTIES VERSION 1.0.1) + add_executable(testEXE main.cpp) target_link_libraries(testEXE cmModLib) |