diff options
-rw-r--r-- | docs/markdown/Release-notes-for-0.55.0.md | 8 | ||||
-rw-r--r-- | mesonbuild/cmake/executor.py | 7 | ||||
-rw-r--r-- | mesonbuild/coredata.py | 42 | ||||
-rw-r--r-- | mesonbuild/dependencies/base.py | 5 | ||||
-rw-r--r-- | mesonbuild/environment.py | 9 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 2 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 2 | ||||
-rw-r--r-- | mesonbuild/optinterpreter.py | 2 | ||||
-rwxr-xr-x | run_unittests.py | 10 | ||||
-rw-r--r-- | test cases/common/213 tap tests/cat.c | 26 | ||||
-rw-r--r-- | test cases/common/213 tap tests/issue7515.txt | 27 | ||||
-rw-r--r-- | test cases/common/213 tap tests/meson.build | 3 | ||||
l--------- | test cases/common/227 fs module/a_symlink | 1 | ||||
-rw-r--r-- | test cases/common/227 fs module/meson.build | 24 | ||||
-rw-r--r-- | test cases/failing test/5 tap tests/meson.build | 1 | ||||
-rw-r--r-- | test cases/frameworks/1 boost/meson.build | 6 |
16 files changed, 130 insertions, 45 deletions
diff --git a/docs/markdown/Release-notes-for-0.55.0.md b/docs/markdown/Release-notes-for-0.55.0.md index 534c452..cd3f795 100644 --- a/docs/markdown/Release-notes-for-0.55.0.md +++ b/docs/markdown/Release-notes-for-0.55.0.md @@ -305,3 +305,11 @@ $ meson compile "--ninja-args=['a,b', 'c d']" dumping the AST (--ast): **new in 0.55.0** - prints the AST of a meson.build as JSON +## `--backend=vs` now matches `-Db_vscrt=from_buildtype` behaviour in the Ninja backend + +When `--buildtype=debugoptimized` is used with the Ninja backend, the VS CRT +option used is `/MD`, which is the [behaviour documented for all +backends](https://mesonbuild.com/Builtin-options.html#b_vscrt-from_buildtype). +However, the Visual Studio backend was pass `/MT` in that case, which is inconsistent. + +If you need to use the MultiThreaded CRT, you should explicitly pass `-Db_vscrt=mt` diff --git a/mesonbuild/cmake/executor.py b/mesonbuild/cmake/executor.py index 148a999..0075e06 100644 --- a/mesonbuild/cmake/executor.py +++ b/mesonbuild/cmake/executor.py @@ -69,7 +69,12 @@ class CMakeExecutor: self.environment.is_cross_build(), 'CMAKE_PREFIX_PATH') if env_pref_path is not None: - env_pref_path = re.split(r':|;', env_pref_path) + if mesonlib.is_windows(): + # Cannot split on ':' on Windows because its in the drive letter + env_pref_path = env_pref_path.split(os.pathsep) + else: + # https://github.com/mesonbuild/meson/issues/7294 + env_pref_path = re.split(r':|;', env_pref_path) env_pref_path = [x for x in env_pref_path if x] # Filter out empty strings if not self.prefix_paths: self.prefix_paths = [] diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 724e111..ce03fbc 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -45,6 +45,16 @@ default_yielding = False # Can't bind this near the class method it seems, sadly. _T = T.TypeVar('_T') +class MesonVersionMismatchException(MesonException): + '''Build directory generated with Meson version incompatible with current version''' + def __init__(self, old_version, current_version): + super().__init__('Build directory has been generated with Meson version {}, ' + 'which is incompatible with current version {}.' + .format(old_version, current_version)) + self.old_version = old_version + self.current_version = current_version + + class UserOption(T.Generic[_T]): def __init__(self, description, choices, yielding): super().__init__() @@ -450,7 +460,7 @@ class CoreData: # getting the "system default" is always wrong on multiarch # platforms as it gets a value like lib/x86_64-linux-gnu. if self.cross_files: - builtin_options['libdir'].default = 'lib' + BUILTIN_OPTIONS['libdir'].default = 'lib' def sanitize_prefix(self, prefix): prefix = os.path.expanduser(prefix) @@ -506,10 +516,10 @@ class CoreData: def init_builtins(self, subproject: str): # Create builtin options with default values - for key, opt in builtin_options.items(): + for key, opt in BUILTIN_OPTIONS.items(): self.add_builtin_option(self.builtins, key, opt, subproject) for for_machine in iter(MachineChoice): - for key, opt in builtin_options_per_machine.items(): + for key, opt in BUILTIN_OPTIONS_PER_MACHINE.items(): self.add_builtin_option(self.builtins_per_machine[for_machine], key, opt, subproject) def add_builtin_option(self, opts_map, key, opt, subproject): @@ -714,7 +724,7 @@ class CoreData: self.builtins['prefix'].set_value(prefix) for key in builtin_dir_noprefix_options: if key not in options: - self.builtins[key].set_value(builtin_options[key].prefixed_default(key, prefix)) + self.builtins[key].set_value(BUILTIN_OPTIONS[key].prefixed_default(key, prefix)) unknown_options = [] for k, v in options.items(): @@ -770,7 +780,7 @@ class CoreData: for k, v in chain(env.meson_options.build.get('', {}).items(), env.meson_options.build.get(subproject, {}).items()): - if k in builtin_options_per_machine: + if k in BUILTIN_OPTIONS_PER_MACHINE: options[make_key('build.{}'.format(k))] = v options.update({make_key(k): v for k, v in env.user_options.get(subproject, {}).items()}) @@ -780,7 +790,7 @@ class CoreData: # put those options into env.meson_options, only if they're not already # in there, as the machine files and command line have precendence. for k, v in default_options.items(): - if k in builtin_options and not builtin_options[k].yielding: + if k in BUILTIN_OPTIONS and not BUILTIN_OPTIONS[k].yielding: continue for machine in MachineChoice: if machine is MachineChoice.BUILD and not self.is_cross_build(): @@ -982,9 +992,7 @@ def load(build_dir): if not isinstance(obj, CoreData): raise MesonException(load_fail_msg) if major_versions_differ(obj.version, version): - raise MesonException('Build directory has been generated with Meson version %s, ' - 'which is incompatible with current version %s.\n' % - (obj.version, version)) + raise MesonVersionMismatchException(obj.version, version) return obj def save(obj, build_dir): @@ -1005,9 +1013,9 @@ def save(obj, build_dir): def register_builtin_arguments(parser): - for n, b in builtin_options.items(): + for n, b in BUILTIN_OPTIONS.items(): b.add_to_argparse(n, parser, '', '') - for n, b in builtin_options_per_machine.items(): + for n, b in BUILTIN_OPTIONS_PER_MACHINE.items(): b.add_to_argparse(n, parser, '', ' (just for host machine)') b.add_to_argparse(n, parser, 'build.', ' (just for build machine)') parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option", @@ -1028,9 +1036,9 @@ def parse_cmd_line_options(args): # Merge builtin options set with --option into the dict. for name in chain( - builtin_options.keys(), - ('build.' + k for k in builtin_options_per_machine.keys()), - builtin_options_per_machine.keys(), + BUILTIN_OPTIONS.keys(), + ('build.' + k for k in BUILTIN_OPTIONS_PER_MACHINE.keys()), + BUILTIN_OPTIONS_PER_MACHINE.keys(), ): value = getattr(args, name, None) if value is not None: @@ -1157,9 +1165,9 @@ BUILTIN_CORE_OPTIONS = OrderedDict([ ('force_fallback_for', BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])), ]) # type: OptionDictType -builtin_options = OrderedDict(chain(BUILTIN_DIR_OPTIONS.items(), BUILTIN_CORE_OPTIONS.items())) +BUILTIN_OPTIONS = OrderedDict(chain(BUILTIN_DIR_OPTIONS.items(), BUILTIN_CORE_OPTIONS.items())) -builtin_options_per_machine = OrderedDict([ +BUILTIN_OPTIONS_PER_MACHINE = OrderedDict([ ('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])), ('cmake_prefix_path', BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [])), ]) @@ -1172,7 +1180,7 @@ builtin_dir_noprefix_options = { 'sharedstatedir': {'/usr': '/var/lib', '/usr/local': '/var/local/lib'}, } -forbidden_target_names = {'clean': None, +FORBIDDEN_TARGET_NAMES = {'clean': None, 'clean-ctlist': None, 'clean-gcno': None, 'clean-gcda': None, diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index c726a7e..368a4bc 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -1450,7 +1450,10 @@ class CMakeDependency(ExternalDependency): cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x] cfg = cfgs[0] - is_debug = self.env.coredata.get_builtin_option('debug'); + is_debug = self.env.coredata.get_builtin_option('buildtype') == 'debug' + if 'b_vscrt' in self.env.coredata.base_options: + if self.env.coredata.base_options['b_vscrt'].value in ('mdd', 'mtd'): + is_debug = True if is_debug: if 'DEBUG' in cfgs: cfg = 'DEBUG' diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index bf75c80..6987863 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -523,6 +523,11 @@ class Environment: self.first_invocation = False except FileNotFoundError: self.create_new_coredata(options) + except coredata.MesonVersionMismatchException as e: + # This is routine, but tell the user the update happened + mlog.log('Regenerating configuration from scratch:', str(e)) + coredata.read_cmd_line_file(self.build_dir, options) + self.create_new_coredata(options) except MesonException as e: # If we stored previous command line options, we can recover from # a broken/outdated coredata. @@ -701,7 +706,7 @@ class Environment: # Read in command line and populate options # TODO: validate all of this - all_builtins = set(coredata.builtin_options) | set(coredata.builtin_options_per_machine) | set(coredata.builtin_dir_noprefix_options) + all_builtins = set(coredata.BUILTIN_OPTIONS) | set(coredata.BUILTIN_OPTIONS_PER_MACHINE) | set(coredata.builtin_dir_noprefix_options) for k, v in options.cmd_line_options.items(): try: subproject, k = k.split(':') @@ -716,7 +721,7 @@ class Environment: self.meson_options.host[subproject][k] = v elif k.startswith('build.'): k = k.lstrip('build.') - if k in coredata.builtin_options_per_machine: + if k in coredata.BUILTIN_OPTIONS_PER_MACHINE: if self.meson_options.build is None: self.meson_options.build = collections.defaultdict(dict) self.meson_options.build[subproject][k] = v diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index cf7f282..fbe0374 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -4685,7 +4685,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s 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: + if name in coredata.FORBIDDEN_TARGET_NAMES: 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 diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 0d81692..817550e 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -489,7 +489,7 @@ class TestRun: failed = True elif isinstance(i, TAPParser.Test): results.append(i.result) - if i.result not in {TestResult.OK, TestResult.EXPECTEDFAIL}: + if i.result not in {TestResult.OK, TestResult.EXPECTEDFAIL, TestResult.SKIP}: failed = True elif isinstance(i, TAPParser.Error): results.append(TestResult.ERROR) diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py index d47a3d2..a6fd503 100644 --- a/mesonbuild/optinterpreter.py +++ b/mesonbuild/optinterpreter.py @@ -22,7 +22,7 @@ from . import mesonlib from . import mparser from .interpreterbase import FeatureNew -forbidden_option_names = set(coredata.builtin_options.keys()) +forbidden_option_names = set(coredata.BUILTIN_OPTIONS.keys()) forbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_'] reserved_prefixes = ['cross_'] diff --git a/run_unittests.py b/run_unittests.py index 6d7eba2..49e2206 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1372,8 +1372,8 @@ class DataTests(unittest.TestCase): found_entries |= options self.assertEqual(found_entries, set([ - *mesonbuild.coredata.builtin_options.keys(), - *mesonbuild.coredata.builtin_options_per_machine.keys() + *mesonbuild.coredata.BUILTIN_OPTIONS.keys(), + *mesonbuild.coredata.BUILTIN_OPTIONS_PER_MACHINE.keys() ])) # Check that `buildtype` table inside `Core options` matches how @@ -3037,7 +3037,7 @@ int main(int argc, char **argv) { test. Needs to be a unit test because it accesses Meson internals. ''' testdir = os.path.join(self.common_test_dir, '154 reserved targets') - targets = mesonbuild.coredata.forbidden_target_names + targets = mesonbuild.coredata.FORBIDDEN_TARGET_NAMES # We don't actually define a target with this name targets.pop('build.ninja') # Remove this to avoid multiple entries with the same name @@ -4030,7 +4030,7 @@ recommended as it is not supported on some platforms''') self.__reconfigure() out = self.init(testdir, extra_args=['--reconfigure', '-Dopt3=val3']) - self.assertRegex(out, 'WARNING:.*Regenerating configuration from scratch') + self.assertRegex(out, 'Regenerating configuration from scratch') self.assertRegex(out, 'opt1 val1') self.assertRegex(out, 'opt2 val2') self.assertRegex(out, 'opt3 val3') @@ -4067,7 +4067,7 @@ recommended as it is not supported on some platforms''') self.__reconfigure(change_minor=True) out = self.init(testdir, extra_args=['--reconfigure', '-Dopt3=val3']) - self.assertNotRegex(out, 'WARNING:.*Regenerating configuration from scratch') + self.assertNotRegex(out, 'Regenerating configuration from scratch') self.assertRegex(out, 'opt1 val1') self.assertRegex(out, 'opt2 val2') self.assertRegex(out, 'opt3 val3') diff --git a/test cases/common/213 tap tests/cat.c b/test cases/common/213 tap tests/cat.c new file mode 100644 index 0000000..4b92010 --- /dev/null +++ b/test cases/common/213 tap tests/cat.c @@ -0,0 +1,26 @@ +#include <errno.h> +#include <stdio.h> + +int main(int argc, char **argv) { + char buf[1024]; + size_t len; + FILE *fh; + + if (argc != 2) { + fprintf(stderr, "Incorrect number of arguments, got %i\n", argc); + return 1; + } + fh = fopen(argv[1], "r"); + if (fh == NULL) { + fprintf(stderr, "Opening %s: errno=%i\n", argv[1], errno); + return 1; + } + do { + len = fread(buf, 1, sizeof(buf), fh); + if (len > 0) { + fwrite(buf, 1, len, stdout); + } + } while (len > 0); + fclose(fh); + return 0; +} diff --git a/test cases/common/213 tap tests/issue7515.txt b/test cases/common/213 tap tests/issue7515.txt new file mode 100644 index 0000000..ca85637 --- /dev/null +++ b/test cases/common/213 tap tests/issue7515.txt @@ -0,0 +1,27 @@ +1..26 +ok 1 Gtk overrides UI template sets up internal and public template children +ok 2 Gtk overrides UI template sets up public template children with the correct widgets +ok 3 Gtk overrides UI template sets up internal template children with the correct widgets +ok 4 Gtk overrides UI template connects template callbacks to the correct handler +ok 5 Gtk overrides UI template binds template callbacks to the correct object +ok 6 Gtk overrides UI template from resource sets up internal and public template children +ok 7 Gtk overrides UI template from resource sets up public template children with the correct widgets +ok 8 Gtk overrides UI template from resource sets up internal template children with the correct widgets +ok 9 Gtk overrides UI template from resource connects template callbacks to the correct handler +ok 10 Gtk overrides UI template from resource binds template callbacks to the correct object +ok 11 Gtk overrides UI template from file sets up internal and public template children +ok 12 Gtk overrides UI template from file sets up public template children with the correct widgets +ok 13 Gtk overrides UI template from file sets up internal template children with the correct widgets +ok 14 Gtk overrides UI template from file connects template callbacks to the correct handler +ok 15 Gtk overrides UI template from file binds template callbacks to the correct object +ok 16 Gtk overrides Class inheriting from template class sets up internal and public template children # SKIP pending +ok 17 Gtk overrides Class inheriting from template class sets up public template children with the correct widgets # SKIP pending +ok 18 Gtk overrides Class inheriting from template class sets up internal template children with the correct widgets # SKIP pending +ok 19 Gtk overrides Class inheriting from template class connects template callbacks to the correct handler # SKIP pending +ok 20 Gtk overrides Class inheriting from template class binds template callbacks to the correct object # SKIP pending +ok 21 Gtk overrides sets CSS names on classes +ok 22 Gtk overrides avoid crashing when GTK vfuncs are called in garbage collection +ok 23 Gtk overrides accepts string in place of GdkAtom +ok 24 Gtk overrides accepts null in place of GdkAtom as GDK_NONE +ok 25 Gtk overrides uses the correct GType for null child properties +ok 26 Gtk overrides can create a Gtk.TreeIter with accessible stamp field diff --git a/test cases/common/213 tap tests/meson.build b/test cases/common/213 tap tests/meson.build index 58529a7..c762c73 100644 --- a/test cases/common/213 tap tests/meson.build +++ b/test cases/common/213 tap tests/meson.build @@ -1,10 +1,13 @@ project('test features', 'c') tester = executable('tester', 'tester.c') +cat = executable('cat', 'cat.c') test('pass', tester, args : ['ok'], protocol: 'tap') test('fail', tester, args : ['not ok'], should_fail: true, protocol: 'tap') test('xfail', tester, args : ['not ok # todo'], protocol: 'tap') test('xpass', tester, args : ['ok # todo'], should_fail: true, protocol: 'tap') test('skip', tester, args : ['ok # skip'], protocol: 'tap') +test('partially skipped', tester, args : ['ok 1\nok 2 # skip'], protocol: 'tap') +test('partially skipped (real-world example)', cat, args : [files('issue7515.txt')], protocol: 'tap') test('skip failure', tester, args : ['not ok # skip'], should_fail: true, protocol: 'tap') test('no tests', tester, args : ['1..0 # skip'], protocol: 'tap') diff --git a/test cases/common/227 fs module/a_symlink b/test cases/common/227 fs module/a_symlink deleted file mode 120000 index 25d053a..0000000 --- a/test cases/common/227 fs module/a_symlink +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/test cases/common/227 fs module/meson.build b/test cases/common/227 fs module/meson.build index a732768..cff0987 100644 --- a/test cases/common/227 fs module/meson.build +++ b/test cases/common/227 fs module/meson.build @@ -7,18 +7,14 @@ fs = import('fs') assert(fs.exists('meson.build'), 'Existing file reported as missing.') assert(not fs.exists('nonexisting'), 'Nonexisting file was found.') -# When one creates a source release with sdist, Python -# does not store symlinks in the archive as native symlinks. -# Thus the extracted archive does not contain them either. -# Sadly this means that we can only execute the symlink test when -# running from a git checkout because otherwise we'd need to -# do postprocessing on the generated archive before actual release. -# That is both nonstandard an error prone and having symlinks in -# the archive would probably break on Windows anyway. -is_git_checkout = fs.exists('../../../.git') - -if not is_windows and build_machine.system() != 'cygwin' and is_git_checkout - assert(fs.is_symlink('a_symlink'), 'Symlink not detected.') +if not is_windows and build_machine.system() != 'cygwin' + # Symlinks on Windows have specific requirements including: + # * Meson running under Python >= 3.8 + # * Windows user permissions to create symlinks, and/or Windows in Developer mode + # so at this time the symlink test is skipped for Windows. + symlink = meson.current_build_dir() / 'a_symlink' + run_command('ln', '-s', meson.current_source_dir() / 'meson.build', symlink) + assert(fs.is_symlink(symlink), 'Symlink not detected.') assert(not fs.is_symlink('meson.build'), 'Regular file detected as symlink.') endif @@ -103,8 +99,8 @@ assert(fs.is_samepath(meson.source_root(), 'subdir/..'), 'is_samepath not detect assert(not fs.is_samepath(f1, 'subdir/subdirfile.txt'), 'is_samepath known bad comparison') assert(not fs.is_samepath('not-a-path', f2), 'is_samepath should not error if path(s) do not exist') -if not is_windows and build_machine.system() != 'cygwin' and is_git_checkout - assert(fs.is_samepath('a_symlink', 'meson.build'), 'symlink is_samepath fail') +if not is_windows and build_machine.system() != 'cygwin' + assert(fs.is_samepath(symlink, 'meson.build'), 'symlink is_samepath fail') endif # parts of path diff --git a/test cases/failing test/5 tap tests/meson.build b/test cases/failing test/5 tap tests/meson.build index 844c1f9..c49043b 100644 --- a/test cases/failing test/5 tap tests/meson.build +++ b/test cases/failing test/5 tap tests/meson.build @@ -4,3 +4,4 @@ tester = executable('tester', 'tester.c') test('nonzero return code', tester, args : [], protocol: 'tap') test('missing test', tester, args : ['1..1'], protocol: 'tap') test('incorrect skip', tester, args : ['1..1 # skip\nok 1'], protocol: 'tap') +test('partially skipped', tester, args : ['not ok 1\nok 2 # skip'], protocol: 'tap') diff --git a/test cases/frameworks/1 boost/meson.build b/test cases/frameworks/1 boost/meson.build index 6c23360..5a2e1a1 100644 --- a/test cases/frameworks/1 boost/meson.build +++ b/test cases/frameworks/1 boost/meson.build @@ -54,7 +54,11 @@ python3module = shared_library('python3_module', ['python_module.cpp'], dependen test('Boost linktest', linkexe) test('Boost UTF test', unitexe) test('Boost nomod', nomodexe) -test('Boost extralib test', extralibexe) +if host_machine.system() != 'darwin' or s + # Segfaults on macOS with dynamic linking since Boost 1.73 + # https://github.com/mesonbuild/meson/issues/7535 + test('Boost extralib test', extralibexe) +endif # explicitly use the correct python interpreter so that we don't have to provide two different python scripts that have different shebang lines python2interpreter = find_program(python2.path(), required: false, disabler: true) |