aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/syntax-highlighting/vim/syntax/meson.vim3
-rw-r--r--docs/markdown/Builtin-options.md61
-rw-r--r--docs/markdown/Dependencies.md8
-rw-r--r--docs/markdown/Keyval-module.md4
-rw-r--r--docs/markdown/Reference-manual.md3
-rw-r--r--docs/markdown/Syntax.md20
-rw-r--r--docs/markdown/Vala.md2
-rw-r--r--docs/markdown/snippets/keyval.md7
-rw-r--r--docs/markdown/snippets/per_subproject.md4
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/build.py3
-rw-r--r--mesonbuild/compilers/cpp.py2
-rw-r--r--mesonbuild/compilers/mixins/gnu.py2
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py2
-rw-r--r--mesonbuild/coredata.py7
-rw-r--r--mesonbuild/dependencies/boost.py148
-rw-r--r--mesonbuild/interpreter.py58
-rw-r--r--mesonbuild/interpreterbase.py14
-rw-r--r--mesonbuild/modules/keyval.py (renamed from mesonbuild/modules/unstable_keyval.py)0
-rwxr-xr-xrun_meson_command_tests.py4
-rwxr-xr-xrun_project_tests.py28
-rwxr-xr-xrun_unittests.py11
-rw-r--r--test cases/common/222 source set realistic example/meson.build2
-rw-r--r--test cases/common/230 persubproject options/meson.build4
-rw-r--r--test cases/common/230 persubproject options/subprojects/sub1/foo.c3
-rw-r--r--test cases/common/230 persubproject options/subprojects/sub1/meson.build4
-rw-r--r--test cases/common/38 string operations/meson.build15
-rw-r--r--test cases/frameworks/32 boost root/boost/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib0
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib0
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.00
-rw-r--r--test cases/frameworks/32 boost root/meson.build6
-rw-r--r--test cases/frameworks/32 boost root/nativefile.ini.in2
-rw-r--r--test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib0
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib0
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.00
-rw-r--r--test cases/frameworks/33 boost split root/meson.build6
-rw-r--r--test cases/frameworks/33 boost split root/nativefile.ini.in3
-rw-r--r--test cases/keyval/1 basic/meson.build4
-rw-r--r--test cases/keyval/1 basic/test.json7
-rw-r--r--test cases/keyval/2 subdir/dir/meson.build2
-rw-r--r--test cases/keyval/3 load_config files/dir/meson.build2
-rw-r--r--test cases/keyval/4 load_config builddir/meson.build2
-rw-r--r--test cases/unit/73 summary/meson.build1
-rw-r--r--test cases/windows/17 msvc ndebug/main.cpp9
-rw-r--r--test cases/windows/17 msvc ndebug/meson.build7
47 files changed, 383 insertions, 97 deletions
diff --git a/data/syntax-highlighting/vim/syntax/meson.vim b/data/syntax-highlighting/vim/syntax/meson.vim
index d0d15d9..1100113 100644
--- a/data/syntax-highlighting/vim/syntax/meson.vim
+++ b/data/syntax-highlighting/vim/syntax/meson.vim
@@ -32,8 +32,9 @@ set cpo&vim
" http://mesonbuild.com/Syntax.html
syn keyword mesonConditional elif else if endif
-syn keyword mesonRepeat foreach endforeach
+syn keyword mesonRepeat foreach endforeach
syn keyword mesonOperator and not or in
+syn keyword mesonStatement continue break
syn match mesonComment "#.*$" contains=mesonTodo,@Spell
syn keyword mesonTodo FIXME NOTE NOTES TODO XXX contained
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index e7101d5..6234ecf 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -59,27 +59,27 @@ Options that are labeled "per machine" in the table are set per machine. See
the [specifying options per machine](#Specifying-options-per-machine) section
for details.
-| Option | Default value | Description | Is per machine |
-| ------ | ------------- | ----------- | -------------- |
-| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no |
-| backend {ninja, vs,<br>vs2010, vs2015, vs2017, vs2019, xcode} | ninja | Backend to use | no |
-| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no |
-| debug | true | Debug | no |
-| default_library {shared, static, both} | shared | Default library type | no |
-| errorlogs | true | Whether to print the logs from failing tests. | no |
-| install_umask {preserve, 0000-0777} | 022 | Default umask to apply on permissions of installed files | no |
-| layout {mirror,flat} | mirror | Build directory layout | no |
-| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no |
-| pkg_config_path {OS separated path} | '' | Additional paths for pkg-config to search before builtin paths | yes |
-| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes |
-| stdsplit | true | Split stdout and stderr in test logs | no |
-| strip | false | Strip targets on install | no |
-| unity {on, off, subprojects} | off | Unity build | no |
-| unity_size {>=2} | 4 | Unity file block size | no |
-| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
-| werror | false | Treat warnings as errors | no |
-| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
-| force_fallback_for | [] | Force fallback for those dependencies | no |
+| Option | Default value | Description | Is per machine | Is per subproject |
+| ------ | ------------- | ----------- | -------------- | ----------------- |
+| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no | no |
+| backend {ninja, vs,<br>vs2010, vs2015, vs2017, vs2019, xcode} | ninja | Backend to use | no | no |
+| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no | no |
+| debug | true | Debug | no | no |
+| default_library {shared, static, both} | shared | Default library type | no | yes |
+| errorlogs | true | Whether to print the logs from failing tests. | no | no |
+| install_umask {preserve, 0000-0777} | 022 | Default umask to apply on permissions of installed files | no | no |
+| layout {mirror,flat} | mirror | Build directory layout | no | no |
+| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no | no |
+| pkg_config_path {OS separated path} | '' | Additional paths for pkg-config to search before builtin paths | yes | no |
+| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes | no |
+| stdsplit | true | Split stdout and stderr in test logs | no | no |
+| strip | false | Strip targets on install | no | no |
+| unity {on, off, subprojects} | off | Unity build | no | no |
+| unity_size {>=2} | 4 | Unity file block size | no | no |
+| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no | yes |
+| werror | false | Treat warnings as errors | no | yes |
+| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no | no |
+| force_fallback_for | [] | Force fallback for those dependencies | no | no |
<a name="build-type-options"></a>
For setting optimization levels and toggling debug, you can either set the
@@ -215,3 +215,22 @@ the command line, as there was no `build.` prefix. Similarly named fields in
the `[properties]` section of the cross file would effect cross compilers, but
the code paths were fairly different allowing differences in behavior to crop
out.
+
+## Specifying options per subproject
+
+Since *0.54.0* `default_library` and `werror` built-in options can be defined
+per subproject. This is useful for example when building shared libraries in the
+main project, but static link a subproject, or when the main project must build
+with no warnings but some subprojects cannot.
+
+Most of the time this would be used either by the parent project by setting
+subproject's default_options (e.g. `subproject('foo', default_options: 'default_library=static')`),
+or by the user using the command line `-Dfoo:default_library=static`.
+
+The value is overriden in this order:
+- Value from parent project
+- Value from subproject's default_options if set
+- Value from subproject() default_options if set
+- Value from command line if set
+
+Since 0.56.0 `warning_level` can also be defined per subproject.
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index a8f6d8a..b89a0aa 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -288,8 +288,12 @@ You can call `dependency` multiple times with different modules and
use those to link against your targets.
If your boost headers or libraries are in non-standard locations you
-can set the BOOST_ROOT, BOOST_INCLUDEDIR, and/or BOOST_LIBRARYDIR
-environment variables.
+can set the `BOOST_ROOT`, or the `BOOST_INCLUDEDIR` and `BOOST_LIBRARYDIR`
+environment variables. *(added in 0.56.0)* You can also set these
+parameters as `boost_root`, `boost_include`, and `boost_librarydir` in your
+native or cross machine file. Note that machine file variables are
+preferred to environment variables, and that specifying any of these
+disables system-wide search for boost.
You can set the argument `threading` to `single` to use boost
libraries that have been compiled for single-threaded use instead.
diff --git a/docs/markdown/Keyval-module.md b/docs/markdown/Keyval-module.md
index 643265e..afc48fa 100644
--- a/docs/markdown/Keyval-module.md
+++ b/docs/markdown/Keyval-module.md
@@ -1,5 +1,5 @@
---
-short-description: Unstable keyval module
+short-description: Keyval module
authors:
- name: Mark Schulte, Paolo Bonzini
years: [2017, 2019]
@@ -23,7 +23,7 @@ chosen the configuration options), output a ".config" file.
The module may be imported as follows:
``` meson
-keyval = import('unstable-keyval')
+keyval = import('keyval')
```
The following functions will then be available as methods on the object
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 966d408..080fe3e 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1977,6 +1977,9 @@ are immutable, all operations return their results as a new string.
- `startswith(string)`: returns true if string starts with the string
specified as the argument
+- `substring(start,end)` *(since 0.56.0)*: returns a substring specified from start to end.
+ Both `start` and `end` arguments are optional, so, for example, `'foobar'.substring()` will return `'foobar'`.
+
- `strip()`: removes whitespace at the beginning and end of the string.
*(since 0.43.0)* Optionally can take one positional string argument,
and all characters in that string will be stripped.
diff --git a/docs/markdown/Syntax.md b/docs/markdown/Syntax.md
index 7cb39e9..bbe3dbb 100644
--- a/docs/markdown/Syntax.md
+++ b/docs/markdown/Syntax.md
@@ -220,6 +220,26 @@ is_x86 = target.startswith('x86') # boolean value 'true'
is_bsd = target.to_lower().endswith('bsd') # boolean value 'true'
```
+#### .substring()
+
+Since 0.56.0, you can extract a substring from a string.
+
+```meson
+# Similar to the Python str[start:end] syntax
+target = 'x86_FreeBSD'
+platform = target.substring(0, 3) # prefix string value 'x86'
+system = target.substring(4) # suffix string value 'FreeBSD'
+```
+
+The method accepts negative values where negative `start` is relative to the end of
+string `len(string) - start` as well as negative `end`.
+
+```meson
+string = 'foobar'
+target.substring(-5, -3) # => 'oo'
+target.substring(1, -1) # => 'ooba'
+```
+
#### .split(), .join()
```meson
diff --git a/docs/markdown/Vala.md b/docs/markdown/Vala.md
index cbb58a9..0a29847 100644
--- a/docs/markdown/Vala.md
+++ b/docs/markdown/Vala.md
@@ -237,7 +237,7 @@ dependencies = [
dependency('glib-2.0'),
dependency('gobject-2.0'),
meson.get_compiler('c').find_library('foo'),
- meson.get_compiler('vala').find_library('foo', dir: vapi_dir),
+ meson.get_compiler('vala').find_library('foo', dirs: vapi_dir),
]
sources = files('app.vala')
diff --git a/docs/markdown/snippets/keyval.md b/docs/markdown/snippets/keyval.md
new file mode 100644
index 0000000..895de9b
--- /dev/null
+++ b/docs/markdown/snippets/keyval.md
@@ -0,0 +1,7 @@
+## `unstable-keyval` is now stable `keyval`
+
+The `unstable-keyval` has been renamed to `keyval` and now promises stability
+guarantees.
+
+Meson will print a warning when you load an `unstable-` module that has been
+stabilised (so `unstable-keyval` is still accepted for example).
diff --git a/docs/markdown/snippets/per_subproject.md b/docs/markdown/snippets/per_subproject.md
new file mode 100644
index 0000000..6de6068
--- /dev/null
+++ b/docs/markdown/snippets/per_subproject.md
@@ -0,0 +1,4 @@
+## Per subproject `warning_level` option
+
+`warning_level` can now be defined per subproject, in the same way as
+`default_library` and `werror`.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 065da00..3b4a4bd 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -348,7 +348,7 @@ class NinjaBuildElement:
use_rspfile = self._should_use_rspfile()
if use_rspfile:
rulename = self.rulename + '_RSP'
- mlog.log("Command line for building %s is long, using a response file" % self.outfilenames)
+ mlog.debug("Command line for building %s is long, using a response file" % self.outfilenames)
else:
rulename = self.rulename
line = 'build {}{}: {} {}'.format(outs, implicit_outs, rulename, ins)
@@ -459,7 +459,7 @@ int dummy;
# different locales have different messages with a different
# number of colons. Match up to the the drive name 'd:\'.
# When used in cross compilation, the path separator is a
- # backslash rather than a forward slash so handle both.
+ # forward slash rather than a backslash so handle both.
matchre = re.compile(rb"^(.*\s)([a-zA-Z]:\\|\/).*stdio.h$")
def detect_prefix(out):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index d7f3b66..a06979c 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -819,7 +819,8 @@ class BuildTarget(Target):
def get_link_dep_subdirs(self):
result = OrderedSet()
for i in self.link_targets:
- result.add(i.get_subdir())
+ if not isinstance(i, StaticLibrary):
+ result.add(i.get_subdir())
result.update(i.get_link_dep_subdirs())
return result
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 478a68c..f5b0c05 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -577,7 +577,7 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
is_cross: bool, info: 'MachineInfo', exe_wrap, target, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrap, **kwargs)
MSVCCompiler.__init__(self, target)
- self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like
+ self.base_options = ['b_pch', 'b_vscrt', 'b_ndebug'] # FIXME add lto, pgo and the like
self.id = 'msvc'
def get_options(self):
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 3526a91..83f7047 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -362,7 +362,7 @@ class GnuCompiler(GnuLikeCompiler):
# For some compiler command line arguments, the GNU compilers will
# emit a warning on stderr indicating that an option is valid for a
# another language, but still complete with exit_success
- with self._build_wrapper(code, env, args, None, mode, disable_cache=False, want_output=True) as p:
+ with self._build_wrapper(code, env, args, None, mode) as p:
result = p.returncode == 0
if self.language in {'cpp', 'objcpp'} and 'is valid for C/ObjC' in p.stde:
result = False
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index 4dfd8b4..93101b5 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -114,7 +114,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
# See: https://ninja-build.org/manual.html#_deps
always_args = ['/nologo', '/showIncludes']
warn_args = {
- '0': ['/W1'],
+ '0': [],
'1': ['/W2'],
'2': ['/W3'],
'3': ['/W4'],
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 26f33f1..e2a6954 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -19,8 +19,9 @@ from itertools import chain
from pathlib import PurePath
from collections import OrderedDict, defaultdict
from .mesonlib import (
- MesonException, MachineChoice, PerMachine, OrderedSet,
- default_libdir, default_libexecdir, default_prefix, split_args
+ MesonException, EnvironmentException, MachineChoice, PerMachine,
+ OrderedSet, default_libdir, default_libexecdir, default_prefix,
+ split_args
)
from .envconfig import get_env_var_pair
from .wrap import WrapMode
@@ -1181,7 +1182,7 @@ builtin_options = OrderedDict([
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
('unity', BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
('unity_size', BuiltinOption(UserIntegerOption, 'Unity block size', (2, None, 4))),
- ('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
+ ('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'], yielding=False)),
('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False, yielding=False)),
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
('force_fallback_for', BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])),
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 907c0c2..3ad534e 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -20,6 +20,7 @@ from pathlib import Path
from .. import mlog
from .. import mesonlib
+from ..envconfig import get_env_var
from ..environment import Environment
from .base import DependencyException, ExternalDependency, PkgConfigDependency
@@ -163,8 +164,8 @@ class BoostLibraryFile():
if not tags:
return
- # Without any tags mt is assumed, however, an absents of mt in the name
- # with tags present indicates that the lib was build without mt support
+ # Without any tags mt is assumed, however, an absence of mt in the name
+ # with tags present indicates that the lib was built without mt support
self.mt = False
for i in tags:
if i == 'mt':
@@ -367,36 +368,27 @@ class BoostDependency(ExternalDependency):
self.arch = environment.machines[self.for_machine].cpu_family
self.arch = boost_arch_map.get(self.arch, None)
- # Prefere BOOST_INCLUDEDIR and BOOST_LIBRARYDIR if preset
- boost_manual_env = [x in os.environ for x in ['BOOST_INCLUDEDIR', 'BOOST_LIBRARYDIR']]
- if all(boost_manual_env):
- inc_dir = Path(os.environ['BOOST_INCLUDEDIR'])
- lib_dir = Path(os.environ['BOOST_LIBRARYDIR'])
- mlog.debug('Trying to find boost with:')
- mlog.debug(' - BOOST_INCLUDEDIR = {}'.format(inc_dir))
- mlog.debug(' - BOOST_LIBRARYDIR = {}'.format(lib_dir))
-
- boost_inc_dir = None
- for j in [inc_dir / 'version.hpp', inc_dir / 'boost' / 'version.hpp']:
- if j.is_file():
- boost_inc_dir = self._include_dir_from_version_header(j)
- break
- if not boost_inc_dir:
- self.is_found = False
- return
+ # First, look for paths specified in a machine file
+ props = self.env.properties[self.for_machine]
+ boost_property_env = [props.get('boost_includedir'), props.get('boost_librarydir'), props.get('boost_root')]
+ if any(boost_property_env):
+ self.detect_boost_machine_file(props)
+ return
- self.is_found = self.run_check([boost_inc_dir], [lib_dir])
+ # Next, look for paths in the environment
+ boost_manual_env_list = ['BOOST_INCLUDEDIR', 'BOOST_LIBRARYDIR', 'BOOST_ROOT', 'BOOSTROOT']
+ boost_manual_env = [get_env_var(self.for_machine, self.env.is_cross_build, x) for x in boost_manual_env_list]
+ if any(boost_manual_env):
+ self.detect_boost_env()
return
- elif any(boost_manual_env):
- mlog.warning('Both BOOST_INCLUDEDIR *and* BOOST_LIBRARYDIR have to be set (one is not enough). Ignoring.')
- # A) Detect potential boost root directories (uses also BOOST_ROOT env var)
- roots = self.detect_roots()
- roots = list(mesonlib.OrderedSet(roots))
+ # Finally, look for paths from .pc files and from searching the filesystem
+ self.detect_roots()
- # B) Foreach candidate
+ def check_and_set_roots(self, roots) -> None:
+ roots = list(mesonlib.OrderedSet(roots))
for j in roots:
- # 1. Look for the boost headers (boost/version.pp)
+ # 1. Look for the boost headers (boost/version.hpp)
mlog.debug('Checking potential boost root {}'.format(j.as_posix()))
inc_dirs = self.detect_inc_dirs(j)
inc_dirs = sorted(inc_dirs, reverse=True) # Prefer the newer versions
@@ -411,6 +403,74 @@ class BoostDependency(ExternalDependency):
self.boost_root = j
break
+ def detect_boost_machine_file(self, props) -> None:
+ incdir = props.get('boost_includedir')
+ libdir = props.get('boost_librarydir')
+
+ if incdir and libdir:
+ inc_dir = Path(props['boost_includedir'])
+ lib_dir = Path(props['boost_librarydir'])
+
+ if not inc_dir.is_absolute() or not lib_dir.is_absolute():
+ raise DependencyException('Paths given for boost_includedir and boost_librarydir in machine file must be absolute')
+
+ mlog.debug('Trying to find boost with:')
+ mlog.debug(' - boost_includedir = {}'.format(inc_dir))
+ mlog.debug(' - boost_librarydir = {}'.format(lib_dir))
+
+ return self.detect_split_root(inc_dir, lib_dir)
+
+ elif incdir or libdir:
+ raise DependencyException('Both boost_includedir *and* boost_librarydir have to be set in your machine file (one is not enough)')
+
+ rootdir = props.get('boost_root')
+ # It shouldn't be possible to get here without something in boost_root
+ assert(rootdir)
+
+ raw_paths = mesonlib.stringlistify(rootdir)
+ paths = [Path(x) for x in raw_paths]
+ if paths and any([not x.is_absolute() for x in paths]):
+ raise DependencyException('boost_root path given in machine file must be absolute')
+
+ self.check_and_set_roots(paths)
+
+ def detect_boost_env(self):
+ boost_includedir = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_INCLUDEDIR')
+ boost_librarydir = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_LIBRARYDIR')
+
+ boost_manual_env = [boost_includedir, boost_librarydir]
+ if all(boost_manual_env):
+ inc_dir = Path(boost_includedir)
+ lib_dir = Path(boost_librarydir)
+
+ if not inc_dir.is_absolute() or not lib_dir.is_absolute():
+ raise DependencyException('Paths given in BOOST_INCLUDEDIR and BOOST_LIBRARYDIR must be absolute')
+
+ mlog.debug('Trying to find boost with:')
+ mlog.debug(' - BOOST_INCLUDEDIR = {}'.format(inc_dir))
+ mlog.debug(' - BOOST_LIBRARYDIR = {}'.format(lib_dir))
+
+ return self.detect_split_root(inc_dir, lib_dir)
+
+ elif any(boost_manual_env):
+ raise DependencyException('Both BOOST_INCLUDEDIR *and* BOOST_LIBRARYDIR have to be set (one is not enough). Ignoring.')
+
+ boost_root = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_ROOT')
+ boostroot = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOSTROOT')
+
+ # It shouldn't be possible to get here without something in BOOST_ROOT or BOOSTROOT
+ assert(boost_root or boostroot)
+
+ for path, name in [(boost_root, 'BOOST_ROOT'), (boostroot, 'BOOSTROOT')]:
+ if path:
+ raw_paths = path.split(os.pathsep)
+ paths = [Path(x) for x in raw_paths]
+ if paths and any([not x.is_absolute() for x in paths]):
+ raise DependencyException('Paths in {} must be absolute'.format(name))
+ break
+
+ self.check_and_set_roots(paths)
+
def run_check(self, inc_dirs: T.List[BoostIncludeDir], lib_dirs: T.List[Path]) -> bool:
mlog.debug(' - potential library dirs: {}'.format([x.as_posix() for x in lib_dirs]))
mlog.debug(' - potential include dirs: {}'.format([x.path.as_posix() for x in inc_dirs]))
@@ -560,6 +620,12 @@ class BoostDependency(ExternalDependency):
except (KeyError, IndexError, AttributeError):
pass
+ # mlog.debug(' - static: {}'.format(self.static))
+ # mlog.debug(' - not explicit static: {}'.format(not self.explicit_static))
+ # mlog.debug(' - mt: {}'.format(self.multithreading))
+ # mlog.debug(' - version: {}'.format(lib_vers))
+ # mlog.debug(' - arch: {}'.format(self.arch))
+ # mlog.debug(' - vscrt: {}'.format(vscrt))
libs = [x for x in libs if x.static == self.static or not self.explicit_static]
libs = [x for x in libs if x.mt == self.multithreading]
libs = [x for x in libs if x.version_matches(lib_vers)]
@@ -592,20 +658,22 @@ class BoostDependency(ExternalDependency):
libs += [BoostLibraryFile(i)]
return [x for x in libs if x.is_boost()] # Filter out no boost libraries
- def detect_roots(self) -> T.List[Path]:
- roots = [] # type: T.List[Path]
+ def detect_split_root(self, inc_dir, lib_dir) -> None:
+ boost_inc_dir = None
+ for j in [inc_dir / 'version.hpp', inc_dir / 'boost' / 'version.hpp']:
+ if j.is_file():
+ boost_inc_dir = self._include_dir_from_version_header(j)
+ break
+ if not boost_inc_dir:
+ self.is_found = False
+ return
- # Add roots from the environment
- for i in ['BOOST_ROOT', 'BOOSTROOT']:
- if i in os.environ:
- raw_paths = os.environ[i].split(os.pathsep)
- paths = [Path(x) for x in raw_paths]
- if paths and any([not x.is_absolute() for x in paths]):
- raise DependencyException('Paths in {} must be absolute'.format(i))
- roots += paths
- return roots # Do not add system paths if BOOST_ROOT is present
+ self.is_found = self.run_check([boost_inc_dir], [lib_dir])
+
+ def detect_roots(self) -> None:
+ roots = [] # type: T.List[Path]
- # Try getting the BOOST_ROOT from a boost.pc if it exists. This primarely
+ # Try getting the BOOST_ROOT from a boost.pc if it exists. This primarily
# allows BoostDependency to find boost from Conan. See #5438
try:
boost_pc = PkgConfigDependency('boost', self.env, {'required': False})
@@ -660,7 +728,7 @@ class BoostDependency(ExternalDependency):
tmp = [x.resolve() for x in tmp]
roots += tmp
- return roots
+ self.check_and_set_roots(roots)
def log_details(self) -> str:
res = ''
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 11dac38..df81569 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1844,10 +1844,18 @@ class Summary:
if bool_yn and isinstance(i, bool):
formatted_values.append(mlog.green('YES') if i else mlog.red('NO'))
else:
- formatted_values.append(i)
+ formatted_values.append(str(i))
self.sections[section][k] = (formatted_values, list_sep)
self.max_key_len = max(self.max_key_len, len(k))
+ def text_len(self, v):
+ if isinstance(v, str):
+ return len(v)
+ elif isinstance(v, mlog.AnsiDecorator):
+ return len(v.text)
+ else:
+ raise RuntimeError('Expecting only strings or AnsiDecorator')
+
def dump(self):
mlog.log(self.project_name, mlog.normal_cyan(self.project_version))
for section, values in self.sections.items():
@@ -1859,12 +1867,28 @@ class Summary:
indent = self.max_key_len - len(k) + 3
end = ' ' if v else ''
mlog.log(' ' * indent, k + ':', end=end)
- if list_sep is None:
- indent = self.max_key_len + 6
- list_sep = '\n' + ' ' * indent
- mlog.log(*v, sep=list_sep)
+ indent = self.max_key_len + 6
+ self.dump_value(v, list_sep, indent)
mlog.log('') # newline
+ def dump_value(self, arr, list_sep, indent):
+ lines_sep = '\n' + ' ' * indent
+ if list_sep is None:
+ mlog.log(*arr, sep=lines_sep)
+ return
+ max_len = shutil.get_terminal_size().columns
+ line = []
+ line_len = indent
+ lines_sep = list_sep.rstrip() + lines_sep
+ for v in arr:
+ v_len = self.text_len(v) + len(list_sep)
+ if line and line_len + v_len > max_len:
+ mlog.log(*line, sep=list_sep, end=lines_sep)
+ line_len = indent
+ line = []
+ line.append(v)
+ line_len += v_len
+ mlog.log(*line, sep=list_sep)
class MesonMain(InterpreterObject):
def __init__(self, build, interpreter):
@@ -2559,6 +2583,15 @@ class Interpreter(InterpreterBase):
except InvalidArguments:
pass
+ def import_module(self, modname):
+ if modname in self.modules:
+ return
+ try:
+ module = importlib.import_module('mesonbuild.modules.' + modname)
+ except ImportError:
+ raise InvalidArguments('Module "%s" does not exist' % (modname, ))
+ self.modules[modname] = module.initialize(self)
+
@stringArgs
@noKwargs
def func_import(self, node, args, kwargs):
@@ -2567,14 +2600,15 @@ class Interpreter(InterpreterBase):
modname = args[0]
if modname.startswith('unstable-'):
plainname = modname.split('-', 1)[1]
- mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname, location=node)
- modname = 'unstable_' + plainname
- if modname not in self.modules:
try:
- module = importlib.import_module('mesonbuild.modules.' + modname)
- except ImportError:
- raise InvalidArguments('Module "%s" does not exist' % (modname, ))
- self.modules[modname] = module.initialize(self)
+ # check if stable module exists
+ self.import_module(plainname)
+ mlog.warning('Module %s is now stable, please use the %s module instead.' % (modname, plainname))
+ modname = plainname
+ except InvalidArguments:
+ mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname, location=node)
+ modname = 'unstable_' + plainname
+ self.import_module(modname)
return ModuleHolder(modname, self.modules[modname], self)
@stringArgs
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 634f4f2..9f35601 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -1026,6 +1026,20 @@ The result of this is undefined and will become a hard error in a future Meson r
if not isinstance(cmpr, str):
raise InterpreterException('Version_compare() argument must be a string.')
return mesonlib.version_compare(obj, cmpr)
+ elif method_name == 'substring':
+ if len(posargs) > 2:
+ raise InterpreterException('substring() takes maximum two arguments.')
+ start = 0
+ end = len(obj)
+ if len (posargs) > 0:
+ if not isinstance(posargs[0], int):
+ raise InterpreterException('substring() argument must be an int')
+ start = posargs[0]
+ if len (posargs) > 1:
+ if not isinstance(posargs[1], int):
+ raise InterpreterException('substring() argument must be an int')
+ end = posargs[1]
+ return obj[start:end]
raise InterpreterException('Unknown method "%s" for a string.' % method_name)
def format_string(self, templ: str, args: T.List[TYPE_nvar]) -> str:
diff --git a/mesonbuild/modules/unstable_keyval.py b/mesonbuild/modules/keyval.py
index 3da2992..3da2992 100644
--- a/mesonbuild/modules/unstable_keyval.py
+++ b/mesonbuild/modules/keyval.py
diff --git a/run_meson_command_tests.py b/run_meson_command_tests.py
index 6ed3d8f..7bc6185 100755
--- a/run_meson_command_tests.py
+++ b/run_meson_command_tests.py
@@ -129,6 +129,10 @@ class CommandTests(unittest.TestCase):
os.environ['PYTHONPATH'] = os.path.join(str(pylibdir), '')
os.environ['PATH'] = str(bindir) + os.pathsep + os.environ['PATH']
self._run(python_command + ['setup.py', 'install', '--prefix', str(prefix)])
+ # Fix importlib-metadata by appending all dirs in pylibdir
+ PYTHONPATHS = [pylibdir] + [x for x in pylibdir.iterdir()]
+ PYTHONPATHS = [os.path.join(str(x), '') for x in PYTHONPATHS]
+ os.environ['PYTHONPATH'] = os.pathsep.join(PYTHONPATHS)
# Check that all the files were installed correctly
self.assertTrue(bindir.is_dir())
self.assertTrue(pylibdir.is_dir())
diff --git a/run_project_tests.py b/run_project_tests.py
index 9487a04..56b7e2a 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -41,6 +41,7 @@ from mesonbuild import compilers
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mtest
+from mesonbuild.build import ConfigurationData
from mesonbuild.mesonlib import MachineChoice, Popen_safe
from mesonbuild.coredata import backendlist, version as meson_version
@@ -475,6 +476,28 @@ def create_deterministic_builddir(test: TestDef, use_tmpdir: bool) -> str:
os.mkdir(abs_pathname)
return abs_pathname
+def format_parameter_file(file_basename: str, test: TestDef, test_build_dir: str) -> Path:
+ confdata = ConfigurationData()
+ confdata.values = {'MESON_TEST_ROOT': (str(test.path.absolute()), 'base directory of current test')}
+
+ template = test.path / (file_basename + '.in')
+ destination = Path(test_build_dir) / file_basename
+ mesonlib.do_conf_file(str(template), str(destination), confdata, 'meson')
+
+ return destination
+
+def detect_parameter_files(test: TestDef, test_build_dir: str) -> (Path, Path):
+ nativefile = test.path / 'nativefile.ini'
+ crossfile = test.path / 'crossfile.ini'
+
+ if os.path.exists(str(test.path / 'nativefile.ini.in')):
+ nativefile = format_parameter_file('nativefile.ini', test, test_build_dir)
+
+ if os.path.exists(str(test.path / 'crossfile.ini.in')):
+ crossfile = format_parameter_file('crossfile.ini', test, test_build_dir)
+
+ return nativefile, crossfile
+
def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail, use_tmp: bool):
if test.skip:
return None
@@ -497,8 +520,9 @@ def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args,
if 'libdir' not in test.do_not_set_opts:
gen_args += ['--libdir', 'lib']
gen_args += [test.path.as_posix(), test_build_dir] + flags + extra_args
- nativefile = test.path / 'nativefile.ini'
- crossfile = test.path / 'crossfile.ini'
+
+ nativefile, crossfile = detect_parameter_files(test, test_build_dir)
+
if nativefile.exists():
gen_args.extend(['--native-file', nativefile.as_posix()])
if crossfile.exists():
diff --git a/run_unittests.py b/run_unittests.py
index 820b705..ff6bb9c 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -4635,6 +4635,10 @@ recommended as it is not supported on some platforms''')
no: NO
coma list: a, b, c
+ Plugins
+ long coma list: alpha, alphacolor, apetag, audiofx, audioparsers, auparse,
+ autodetect, avi
+
Subprojects
sub: YES
sub2: NO Problem encountered: This subproject failed
@@ -7030,6 +7034,13 @@ c = ['{0}']
windows_proof_rmtree(os.path.join(testdir, 'subprojects', 'foo'))
os.unlink(wrap_filename)
+ def test_no_rpath_for_static(self):
+ testdir = os.path.join(self.common_test_dir, '5 linkstatic')
+ self.init(testdir)
+ self.build()
+ build_rpath = get_rpath(os.path.join(self.builddir, 'prog'))
+ self.assertIsNone(build_rpath)
+
class BaseLinuxCrossTests(BasePlatformTests):
# Don't pass --libdir when cross-compiling. We have tests that
diff --git a/test cases/common/222 source set realistic example/meson.build b/test cases/common/222 source set realistic example/meson.build
index 106b81d..d986b99 100644
--- a/test cases/common/222 source set realistic example/meson.build
+++ b/test cases/common/222 source set realistic example/meson.build
@@ -9,7 +9,7 @@ if cppid == 'pgi'
endif
ss = import('sourceset')
-keyval = import('unstable-keyval')
+keyval = import('keyval')
zlib = declare_dependency(compile_args: '-DZLIB=1')
another = declare_dependency(compile_args: '-DANOTHER=1')
diff --git a/test cases/common/230 persubproject options/meson.build b/test cases/common/230 persubproject options/meson.build
index 20dff90..f76a70c 100644
--- a/test cases/common/230 persubproject options/meson.build
+++ b/test cases/common/230 persubproject options/meson.build
@@ -1,9 +1,11 @@
project('persubproject options', 'c',
default_options : ['default_library=both',
- 'werror=true'])
+ 'werror=true',
+ 'warning_level=3'])
assert(get_option('default_library') == 'both', 'Parent default_library should be "both"')
assert(get_option('werror'))
+assert(get_option('warning_level') == '3')
# Check it build both by calling a method only both_libraries target implement
lib = library('lib1', 'foo.c')
diff --git a/test cases/common/230 persubproject options/subprojects/sub1/foo.c b/test cases/common/230 persubproject options/subprojects/sub1/foo.c
index 63e4de6..82ad2c2 100644
--- a/test cases/common/230 persubproject options/subprojects/sub1/foo.c
+++ b/test cases/common/230 persubproject options/subprojects/sub1/foo.c
@@ -1,5 +1,8 @@
int foo(void);
int foo(void) {
+ /* This is built with -Werror, it would error if warning_level=3 was inherited
+ * from main project and not overridden by this subproject's default_options. */
+ int x;
return 0;
}
diff --git a/test cases/common/230 persubproject options/subprojects/sub1/meson.build b/test cases/common/230 persubproject options/subprojects/sub1/meson.build
index 7afc934..4e4bc1b 100644
--- a/test cases/common/230 persubproject options/subprojects/sub1/meson.build
+++ b/test cases/common/230 persubproject options/subprojects/sub1/meson.build
@@ -1,6 +1,8 @@
-project('sub1', 'c')
+project('sub1', 'c',
+ default_options : ['warning_level=0'])
assert(get_option('default_library') == 'both', 'Should inherit parent project default_library')
+assert(get_option('warning_level') == '0')
# Check it build both by calling a method only both_libraries target implement
lib = library('lib1', 'foo.c')
diff --git a/test cases/common/38 string operations/meson.build b/test cases/common/38 string operations/meson.build
index 6596142..8a06a82 100644
--- a/test cases/common/38 string operations/meson.build
+++ b/test cases/common/38 string operations/meson.build
@@ -101,3 +101,18 @@ assert('\\\\n' == bs_bs_n, 'Four backslash broken before n')
assert('\\\\\n' == bs_bs_nl, 'Five backslash broken before n')
assert('\\\\' == bs_bs, 'Double-backslash broken')
assert('\\' == bs, 'Backslash broken')
+
+mysubstring='foobarbaz'
+assert(mysubstring.substring() == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(0) == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(1) == 'oobarbaz', 'substring is broken')
+assert(mysubstring.substring(-5) == 'arbaz', 'substring is broken')
+assert(mysubstring.substring(1, 4) == 'oob', 'substring is broken')
+assert(mysubstring.substring(1,-5) == 'oob', 'substring is broken')
+assert(mysubstring.substring(1, 0) == '', 'substring is broken')
+assert(mysubstring.substring(0, 100) == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(-1, -5) == '', 'substring is broken')
+assert(mysubstring.substring(10, -25) == '', 'substring is broken')
+assert(mysubstring.substring(-4, 2) == '', 'substring is broken')
+assert(mysubstring.substring(10, 9) == '', 'substring is broken')
+assert(mysubstring.substring(8, 10) == 'z', 'substring is broken')
diff --git a/test cases/frameworks/32 boost root/boost/include/boost/version.hpp b/test cases/frameworks/32 boost root/boost/include/boost/version.hpp
new file mode 100644
index 0000000..65e4fab
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 100
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib
diff --git a/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib
diff --git a/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0 b/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0
diff --git a/test cases/frameworks/32 boost root/meson.build b/test cases/frameworks/32 boost root/meson.build
new file mode 100644
index 0000000..50d2f0d
--- /dev/null
+++ b/test cases/frameworks/32 boost root/meson.build
@@ -0,0 +1,6 @@
+project('boosttest', 'cpp')
+
+dep = dependency('boost', modules : 'regex', required: false)
+
+assert(dep.found(), 'expected to find a fake version of boost')
+assert(dep.version() == '0.1.0', 'expected to find version 0.1.0')
diff --git a/test cases/frameworks/32 boost root/nativefile.ini.in b/test cases/frameworks/32 boost root/nativefile.ini.in
new file mode 100644
index 0000000..54510d7
--- /dev/null
+++ b/test cases/frameworks/32 boost root/nativefile.ini.in
@@ -0,0 +1,2 @@
+[properties]
+boost_root = '@MESON_TEST_ROOT@/boost'
diff --git a/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp b/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp
new file mode 100644
index 0000000..3ba19ee
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 200
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib
diff --git a/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib
diff --git a/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0 b/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0
diff --git a/test cases/frameworks/33 boost split root/meson.build b/test cases/frameworks/33 boost split root/meson.build
new file mode 100644
index 0000000..a2353bb
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/meson.build
@@ -0,0 +1,6 @@
+project('boosttest', 'cpp')
+
+dep = dependency('boost', modules : 'regex', required: false)
+
+assert(dep.found(), 'expected to find a fake version of boost')
+assert(dep.version() == '0.2.0', 'expected to find version 0.2.0')
diff --git a/test cases/frameworks/33 boost split root/nativefile.ini.in b/test cases/frameworks/33 boost split root/nativefile.ini.in
new file mode 100644
index 0000000..7bd5ac2
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/nativefile.ini.in
@@ -0,0 +1,3 @@
+[properties]
+boost_includedir = '@MESON_TEST_ROOT@/boost/extra-dir/include'
+boost_librarydir = '@MESON_TEST_ROOT@/boost/lib'
diff --git a/test cases/keyval/1 basic/meson.build b/test cases/keyval/1 basic/meson.build
index fc7ddb3..4207b8e 100644
--- a/test cases/keyval/1 basic/meson.build
+++ b/test cases/keyval/1 basic/meson.build
@@ -1,6 +1,6 @@
project('keyval basic test')
-k = import('unstable-keyval')
+k = import('keyval')
conf = k.load('.config')
if not conf.has_key('CONFIG_VAL1')
@@ -14,3 +14,5 @@ endif
if conf.get('CONFIG_VAL_VAL').to_int() != 4
error('Expected CONFIG_VAL_VAL to be 4')
endif
+
+k = import('unstable-keyval')
diff --git a/test cases/keyval/1 basic/test.json b/test cases/keyval/1 basic/test.json
new file mode 100644
index 0000000..dbdc5af
--- /dev/null
+++ b/test cases/keyval/1 basic/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "WARNING: Module unstable-keyval is now stable, please use the keyval module instead."
+ }
+ ]
+}
diff --git a/test cases/keyval/2 subdir/dir/meson.build b/test cases/keyval/2 subdir/dir/meson.build
index dc1b478..291ad93 100644
--- a/test cases/keyval/2 subdir/dir/meson.build
+++ b/test cases/keyval/2 subdir/dir/meson.build
@@ -1,5 +1,5 @@
-k = import('unstable-keyval')
+k = import('keyval')
conf = k.load(meson.source_root() / '.config')
diff --git a/test cases/keyval/3 load_config files/dir/meson.build b/test cases/keyval/3 load_config files/dir/meson.build
index 43fba13..adc5289 100644
--- a/test cases/keyval/3 load_config files/dir/meson.build
+++ b/test cases/keyval/3 load_config files/dir/meson.build
@@ -1,5 +1,5 @@
-k = import('unstable-keyval')
+k = import('keyval')
conf = k.load(files('config'))
diff --git a/test cases/keyval/4 load_config builddir/meson.build b/test cases/keyval/4 load_config builddir/meson.build
index 1bb0285..6bd83db 100644
--- a/test cases/keyval/4 load_config builddir/meson.build
+++ b/test cases/keyval/4 load_config builddir/meson.build
@@ -1,6 +1,6 @@
project('keyval builddir test')
-k = import('unstable-keyval')
+k = import('keyval')
out_conf = configure_file(input: 'config', output: 'out-config', copy: true)
conf = k.load(out_conf)
diff --git a/test cases/unit/73 summary/meson.build b/test cases/unit/73 summary/meson.build
index df4540d..1bc05ca 100644
--- a/test cases/unit/73 summary/meson.build
+++ b/test cases/unit/73 summary/meson.build
@@ -13,3 +13,4 @@ summary('A number', 1, section: 'Configuration')
summary('yes', true, bool_yn : true, section: 'Configuration')
summary('no', false, bool_yn : true, section: 'Configuration')
summary('coma list', ['a', 'b', 'c'], list_sep: ', ', section: 'Configuration')
+summary('long coma list', ['alpha', 'alphacolor', 'apetag', 'audiofx', 'audioparsers', 'auparse', 'autodetect', 'avi'], list_sep: ', ', section: 'Plugins')
diff --git a/test cases/windows/17 msvc ndebug/main.cpp b/test cases/windows/17 msvc ndebug/main.cpp
new file mode 100644
index 0000000..d647d71
--- /dev/null
+++ b/test cases/windows/17 msvc ndebug/main.cpp
@@ -0,0 +1,9 @@
+int main() {
+#ifdef NDEBUG
+ // NDEBUG is defined
+ return 0;
+#else
+ // NDEBUG is not defined
+ return 1;
+#endif
+} \ No newline at end of file
diff --git a/test cases/windows/17 msvc ndebug/meson.build b/test cases/windows/17 msvc ndebug/meson.build
new file mode 100644
index 0000000..78eaf89
--- /dev/null
+++ b/test cases/windows/17 msvc ndebug/meson.build
@@ -0,0 +1,7 @@
+project('msvc_ndebug', 'cpp',
+ default_options : [ 'b_ndebug=true' ]
+)
+
+exe = executable('exe', 'main.cpp')
+
+test('ndebug', exe)