aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--ci/azure-steps.yml4
-rw-r--r--ciimage/Dockerfile1
-rw-r--r--docs/markdown/Contributing.md6
-rw-r--r--docs/markdown/FAQ.md87
-rw-r--r--docs/markdown/Installing.md21
-rw-r--r--docs/markdown/Reference-manual.md5
-rw-r--r--mesonbuild/backend/backends.py5
-rw-r--r--mesonbuild/backend/xcodebackend.py2
-rw-r--r--mesonbuild/compilers/clike.py88
-rw-r--r--mesonbuild/compilers/compilers.py68
-rw-r--r--mesonbuild/compilers/cpp.py2
-rw-r--r--mesonbuild/coredata.py1
-rw-r--r--mesonbuild/dependencies/dev.py6
-rw-r--r--mesonbuild/envconfig.py4
-rw-r--r--mesonbuild/environment.py3
-rw-r--r--mesonbuild/interpreter.py19
-rw-r--r--mesonbuild/mintro.py2
-rw-r--r--mesonbuild/modules/windows.py4
-rw-r--r--mesonbuild/scripts/dist.py14
-rw-r--r--mesonbuild/scripts/meson_exe.py5
-rwxr-xr-xrun_project_tests.py4
-rwxr-xr-xrun_tests.py18
-rwxr-xr-xrun_unittests.py311
-rw-r--r--test cases/frameworks/15 llvm/meson.build44
-rw-r--r--test cases/frameworks/23 hotdoc/installed_files.txt9
-rw-r--r--test cases/windows/5 resources/res/meson.build3
27 files changed, 511 insertions, 229 deletions
diff --git a/.travis.yml b/.travis.yml
index 7658fa0..8f393f1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@ compiler:
env:
- MESON_ARGS=""
- - MESON_ARGS="--unity=on"
+ - RUN_TESTS_ARGS="--no-unittests" MESON_ARGS="--unity=on"
language:
- cpp
@@ -63,4 +63,4 @@ script:
/bin/sh -c "cd /root && mkdir -p tools; wget -c http://nirbheek.in/files/binaries/ninja/linux-amd64/ninja -O /root/tools/ninja; chmod +x /root/tools/ninja; CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX PATH=/root/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS && chmod -R a+rwX .coverage"
fi
# Ensure that llvm is added after $PATH, otherwise the clang from that llvm install will be used instead of the native apple clang.
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH:$(brew --prefix llvm)/bin MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH:$(brew --prefix llvm)/bin MESON_FIXED_NINJA=1 ./run_tests.py $RUN_TESTS_ARGS --backend=ninja -- $MESON_ARGS ; fi
diff --git a/ci/azure-steps.yml b/ci/azure-steps.yml
index 77f61fe..36e6fb4 100644
--- a/ci/azure-steps.yml
+++ b/ci/azure-steps.yml
@@ -154,6 +154,10 @@ steps:
where.exe python
python --version
+ # Needed for running unit tests in parallel.
+ python -m pip install --upgrade pytest-xdist
+
+
echo ""
echo "Locating cl, rc:"
where.exe cl
diff --git a/ciimage/Dockerfile b/ciimage/Dockerfile
index d5f4816..dc66854 100644
--- a/ciimage/Dockerfile
+++ b/ciimage/Dockerfile
@@ -7,6 +7,7 @@ ENV DC=gdc
RUN sed -i '/^#\sdeb-src /s/^#//' "/etc/apt/sources.list" \
&& apt-get -y update && apt-get -y upgrade \
&& apt-get -y build-dep meson \
+&& apt-get -y install python3-pytest-xdist \
&& apt-get -y install python3-pip libxml2-dev libxslt1-dev cmake libyaml-dev \
&& python3 -m pip install hotdoc codecov \
&& apt-get -y install wget unzip \
diff --git a/docs/markdown/Contributing.md b/docs/markdown/Contributing.md
index f8f1824..d724b75 100644
--- a/docs/markdown/Contributing.md
+++ b/docs/markdown/Contributing.md
@@ -304,3 +304,9 @@ line switches.
- Prefer specific solutions to generic frameworks. Solve the end
user's problems rather than providing them tools to do it
themselves.
+
+- Never use features of the Unix shell (or Windows shell for that
+ matter). Doing things like forwaring output with `>` or invoking
+ multiple commands with `&&` are not permitted. Whenever these sorts
+ of requirements show up, write an internal Python script with the
+ desired functionality and use that instead.
diff --git a/docs/markdown/FAQ.md b/docs/markdown/FAQ.md
index e5b7a9c..06379ae 100644
--- a/docs/markdown/FAQ.md
+++ b/docs/markdown/FAQ.md
@@ -402,3 +402,90 @@ the form `foo.lib` when building with MSVC, you can set the
kwarg to `''` and the [`name_suffix:`](https://mesonbuild.com/Reference-manual.html#library)
kwarg to `'lib'`. To get the default behaviour for each, you can either not
specify the kwarg, or pass `[]` (an empty array) to it.
+
+## Do I need to add my headers to the sources list like in Autotools?
+
+Autotools requires you to add private and public headers to the sources list so
+that it knows what files to include in the tarball generated by `make dist`.
+Meson's `dist` command simply gathers everything committed to your git/hg
+repository and adds it to the tarball, so adding headers to the sources list is
+pointless.
+
+Meson uses Ninja which uses compiler dependency information to automatically
+figure out dependencies between C sources and headers, so it will rebuild
+things correctly when a header changes.
+
+The only exception to this are generated headers, for which you must [declare
+dependencies correctly](#how-do-i-tell-meson-that-my-sources-use-generated-headers).
+
+If, for whatever reason, you do add non-generated headers to the sources list
+of a target, Meson will simply ignore them.
+
+## How do I tell Meson that my sources use generated headers?
+
+Let's say you use a [`custom_target()`](https://mesonbuild.com/Reference-manual.html#custom_target)
+to generate the headers, and then `#include` them in your C code. Here's how
+you ensure that Meson generates the headers before trying to compile any
+sources in the build target:
+
+```meson
+libfoo_gen_headers = custom_target('gen-headers', ..., output: 'foo-gen.h')
+libfoo_sources = files('foo-utils.c', 'foo-lib.c')
+# Add generated headers to the list of sources for the build target
+libfoo = library('foo', sources: libfoo_sources + libfoo_gen_headers)
+```
+
+Now let's say you have a new target that links to `libfoo`:
+
+```meson
+libbar_sources = files('bar-lib.c')
+libbar = library('bar', sources: libbar_sources, link_with: libfoo)
+```
+
+This adds a **link-time** dependency between the two targets, but note that the
+sources of the targets have **no compile-time** dependencies and can be built
+in any order; which improves parallelism and speeds up builds.
+
+If the sources in `libbar` *also* use `foo-gen.h`, that's a *compile-time*
+dependency, and you'll have to add `libfoo_gen_headers` to `sources:` for
+`libbar` too:
+
+```meson
+libbar_sources = files('bar-lib.c')
+libbar = library('bar', sources: libbar_sources + libfoo_gen_headers, link_with: libfoo)
+```
+
+Alternatively, if you have multiple libraries with sources that link to
+a library and also use its generated headers, this code is equivalent to above:
+
+```meson
+# Add generated headers to the list of sources for the build target
+libfoo = library('foo', sources: libfoo_sources + libfoo_gen_headers)
+
+# Declare a dependency that will add the generated headers to sources
+libfoo_dep = declare_dependency(link_with: libfoo, sources: libfoo_gen_headers)
+
+...
+
+libbar = library('bar', sources: libbar_sources, dependencies: libfoo_dep)
+```
+
+**Note:** You should only add *headers* to `sources:` while declaring
+a dependency. If your custom target outputs both sources and headers, you can
+use the subscript notation to get only the header(s):
+
+```meson
+libfoo_gen_sources = custom_target('gen-headers', ..., output: ['foo-gen.h', 'foo-gen.c'])
+libfoo_gen_headers = libfoo_gen_sources[0]
+
+# Add static and generated sources to the target
+libfoo = library('foo', sources: libfoo_sources + libfoo_gen_sources)
+
+# Declare a dependency that will add the generated *headers* to sources
+libfoo_dep = declare_dependency(link_with: libfoo, sources: libfoo_gen_headers)
+...
+libbar = library('bar', sources: libbar_sources, dependencies: libfoo_dep)
+```
+
+A good example of a generator that outputs both sources and headers is
+[`gnome.mkenums()`](https://mesonbuild.com/Gnome-module.html#gnomemkenums).
diff --git a/docs/markdown/Installing.md b/docs/markdown/Installing.md
index 66d090d..5abfdd4 100644
--- a/docs/markdown/Installing.md
+++ b/docs/markdown/Installing.md
@@ -115,3 +115,24 @@ command in the build tree:
```console
$ meson install --no-rebuild --only-changed
```
+
+## Finer control over install locations
+
+Sometimes it is necessary to only install a subsection of output files
+or install them in different directories. This can be done by
+specifying `install_dir` as an array rather than a single string. The
+array must have as many items as there are outputs and each entry
+specifies how the corresponding output file should be installed. For
+example:
+
+```meson
+custom_target(...
+ output: ['file1', 'file2', 'file3'],
+ install_dir: ['path1', false, 'path3'],
+ ...
+)
+```
+
+In this case `file1` would be installed to `/prefix/path1/file1`,
+`file2` would not be installed at all and `file3` would be installed
+to `/prefix/path3/file3'.
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 9c98547..3793ce3 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -52,7 +52,7 @@ Like `add_global_arguments` but the arguments are passed to the linker.
### add_languages()
``` meson
- add_languages(*langs*)
+ bool add_languages(*langs*)
```
Add support for new programming languages. Equivalent to having them
@@ -64,6 +64,9 @@ project('foobar', 'c')
if compiling_for_osx
add_languages('objc')
endif
+if add_languages('cpp', required : false)
+ executable('cpp-app', 'main.cpp')
+endif
```
Takes one keyword argument, `required`. It defaults to `true`, which
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index b9bf166..982b0ee 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -812,11 +812,6 @@ class Backend:
true. You might want to set `native: true` instead to build it for
the build machine.'''.format(exe.name))
raise MesonException(s)
- else:
- mlog.warning('''
- Target {} is used as a generator, but is built for the host
- machine. This means most cross builds will fail. You might want to
- set `native: true` instead to build it for the build machine.'''.format(exe.name))
exe_arr = [os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe))]
else:
exe_arr = exe.get_command()
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 7c66250..5bd8106 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -738,7 +738,7 @@ class XCodeBackend(backends.Backend):
ldstr = ' '.join(ldargs)
valid = self.buildconfmap[target_name][buildtype]
langargs = {}
- for lang in self.environment.coredata.compilers:
+ for lang in self.environment.coredata.compilers[target.for_machine]:
if lang not in langnamemap:
continue
# Add compile args added using add_project_arguments()
diff --git a/mesonbuild/compilers/clike.py b/mesonbuild/compilers/clike.py
index 4335b81..046ffba 100644
--- a/mesonbuild/compilers/clike.py
+++ b/mesonbuild/compilers/clike.py
@@ -160,61 +160,10 @@ class CLikeCompiler:
def get_std_shared_lib_link_args(self):
return ['-shared']
- @functools.lru_cache()
- def _get_search_dirs(self, env):
- extra_args = ['--print-search-dirs']
- stdo = None
- with self._build_wrapper('', env, extra_args=extra_args,
- dependencies=None, mode='compile',
- want_output=True) as p:
- stdo = p.stdo
- return stdo
-
- def _split_fetch_real_dirs(self, pathstr):
- # We need to use the path separator used by the compiler for printing
- # lists of paths ("gcc --print-search-dirs"). By default
- # we assume it uses the platform native separator.
- pathsep = os.pathsep
-
- # clang uses ':' instead of ';' on Windows https://reviews.llvm.org/D61121
- # so we need to repair things like 'C:\foo:C:\bar'
- if pathsep == ';':
- pathstr = re.sub(r':([^/\\])', r';\1', pathstr)
-
- # pathlib treats empty paths as '.', so filter those out
- paths = [p for p in pathstr.split(pathsep) if p]
-
- result = []
- for p in paths:
- # GCC returns paths like this:
- # /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib
- # It would make sense to normalize them to get rid of the .. parts
- # Sadly when you are on a merged /usr fs it also kills these:
- # /lib/x86_64-linux-gnu
- # since /lib is a symlink to /usr/lib. This would mean
- # paths under /lib would be considered not a "system path",
- # which is wrong and breaks things. Store everything, just to be sure.
- pobj = Path(p)
- unresolved = pobj.as_posix()
- if pobj.exists():
- if unresolved not in result:
- result.append(unresolved)
- try:
- resolved = Path(p).resolve().as_posix()
- if resolved not in result:
- result.append(resolved)
- except FileNotFoundError:
- pass
- return tuple(result)
-
def get_compiler_dirs(self, env, name):
'''
Get dirs from the compiler, either `libraries:` or `programs:`
'''
- stdo = self._get_search_dirs(env)
- for line in stdo.split('\n'):
- if line.startswith(name + ':'):
- return self._split_fetch_real_dirs(line.split('=', 1)[1])
return ()
@functools.lru_cache()
@@ -384,18 +333,22 @@ class CLikeCompiler:
# Select a CRT if needed since we're linking
if mode == 'link':
args += self.get_linker_debug_crt_args()
- if mode in {'compile', 'preprocess'}:
- # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
- sys_args = env.coredata.get_external_args(self.for_machine, self.language)
- # Apparently it is a thing to inject linker flags both
- # via CFLAGS _and_ LDFLAGS, even though the former are
- # also used during linking. These flags can break
- # argument checks. Thanks, Autotools.
- cleaned_sys_args = self.remove_linkerlike_args(sys_args)
- args += cleaned_sys_args
- elif mode == 'link':
+
+ # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
+ sys_args = env.coredata.get_external_args(self.for_machine, self.language)
+ # Apparently it is a thing to inject linker flags both
+ # via CFLAGS _and_ LDFLAGS, even though the former are
+ # also used during linking. These flags can break
+ # argument checks. Thanks, Autotools.
+ cleaned_sys_args = self.remove_linkerlike_args(sys_args)
+ args += cleaned_sys_args
+
+ if mode == 'link':
# Add LDFLAGS from the env
- args += env.coredata.get_external_link_args(self.for_machine, self.language)
+ sys_ld_args = env.coredata.get_external_link_args(self.for_machine, self.language)
+ # CFLAGS and CXXFLAGS go to both linking and compiling, but we want them
+ # to only appear on the command line once. Remove dupes.
+ args += [x for x in sys_ld_args if x not in sys_args]
args += self.get_compiler_args_for_mode(mode)
return args
@@ -431,11 +384,11 @@ class CLikeCompiler:
with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p:
return p.returncode == 0, p.cached
- def _build_wrapper(self, code, env, extra_args, dependencies=None, mode='compile', want_output=False, disable_cache=False):
+ def _build_wrapper(self, code, env, extra_args, dependencies=None, mode='compile', want_output=False, disable_cache=False, temp_dir=None):
args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
if disable_cache or want_output:
- return self.compile(code, extra_args=args, mode=mode, want_output=want_output)
- return self.cached_compile(code, env.coredata, extra_args=args, mode=mode)
+ return self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir)
+ return self.cached_compile(code, env.coredata, extra_args=args, mode=mode, temp_dir=env.scratch_dir)
def links(self, code, env, *, extra_args=None, dependencies=None, disable_cache=False):
return self.compiles(code, env, extra_args=extra_args,
@@ -550,6 +503,7 @@ class CLikeCompiler:
{prefix}
int main(int argc, char **argv) {{
{type} something;
+ return 0;
}}'''
if not self.compiles(t.format(**fargs), env, extra_args=extra_args,
dependencies=dependencies)[0]:
@@ -639,7 +593,7 @@ class CLikeCompiler:
mode='preprocess').to_native()
func = lambda: self.cached_compile(code.format(**fargs), env.coredata, extra_args=args, mode='preprocess')
if disable_cache:
- func = lambda: self.compile(code.format(**fargs), extra_args=args, mode='preprocess')
+ func = lambda: self.compile(code.format(**fargs), extra_args=args, mode='preprocess', temp_dir=env.scratch_dir)
with func() as p:
cached = p.cached
if p.returncode != 0:
@@ -860,7 +814,7 @@ class CLikeCompiler:
'''
args = self.get_compiler_check_args()
n = 'symbols_have_underscore_prefix'
- with self.compile(code, extra_args=args, mode='compile', want_output=True) as p:
+ with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p:
if p.returncode != 0:
m = 'BUG: Unable to compile {!r} check: {}'
raise RuntimeError(m.format(n, p.stdo))
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 86c1e33..8800923 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -13,8 +13,10 @@
# limitations under the License.
import abc, contextlib, enum, os.path, re, tempfile, shlex
+import functools
import subprocess
from typing import List, Optional, Tuple
+from pathlib import Path
from ..linkers import StaticLinker
from .. import coredata
@@ -1152,11 +1154,11 @@ class Compiler:
return args
@contextlib.contextmanager
- def compile(self, code, extra_args=None, *, mode='link', want_output=False):
+ def compile(self, code, extra_args=None, *, mode='link', want_output=False, temp_dir=None):
if extra_args is None:
extra_args = []
try:
- with tempfile.TemporaryDirectory() as tmpdirname:
+ with tempfile.TemporaryDirectory(dir=temp_dir) as tmpdirname:
if isinstance(code, str):
srcname = os.path.join(tmpdirname,
'testfile.' + self.default_suffix)
@@ -1201,7 +1203,7 @@ class Compiler:
pass
@contextlib.contextmanager
- def cached_compile(self, code, cdata: coredata.CoreData, *, extra_args=None, mode: str = 'link'):
+ def cached_compile(self, code, cdata: coredata.CoreData, *, extra_args=None, mode: str = 'link', temp_dir=None):
assert(isinstance(cdata, coredata.CoreData))
# Calculate the key
@@ -1210,7 +1212,7 @@ class Compiler:
# Check if not cached
if key not in cdata.compiler_check_cache:
- with self.compile(code, extra_args=extra_args, mode=mode, want_output=False) as p:
+ with self.compile(code, extra_args=extra_args, mode=mode, want_output=False, temp_dir=temp_dir) as p:
# Remove all attributes except the following
# This way the object can be serialized
tokeep = ['args', 'commands', 'input_name', 'output_name',
@@ -2005,6 +2007,64 @@ class GnuLikeCompiler(abc.ABC):
return parameter_list
+ @functools.lru_cache()
+ def _get_search_dirs(self, env):
+ extra_args = ['--print-search-dirs']
+ stdo = None
+ with self._build_wrapper('', env, extra_args=extra_args,
+ dependencies=None, mode='compile',
+ want_output=True) as p:
+ stdo = p.stdo
+ return stdo
+
+ def _split_fetch_real_dirs(self, pathstr):
+ # We need to use the path separator used by the compiler for printing
+ # lists of paths ("gcc --print-search-dirs"). By default
+ # we assume it uses the platform native separator.
+ pathsep = os.pathsep
+
+ # clang uses ':' instead of ';' on Windows https://reviews.llvm.org/D61121
+ # so we need to repair things like 'C:\foo:C:\bar'
+ if pathsep == ';':
+ pathstr = re.sub(r':([^/\\])', r';\1', pathstr)
+
+ # pathlib treats empty paths as '.', so filter those out
+ paths = [p for p in pathstr.split(pathsep) if p]
+
+ result = []
+ for p in paths:
+ # GCC returns paths like this:
+ # /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib
+ # It would make sense to normalize them to get rid of the .. parts
+ # Sadly when you are on a merged /usr fs it also kills these:
+ # /lib/x86_64-linux-gnu
+ # since /lib is a symlink to /usr/lib. This would mean
+ # paths under /lib would be considered not a "system path",
+ # which is wrong and breaks things. Store everything, just to be sure.
+ pobj = Path(p)
+ unresolved = pobj.as_posix()
+ if pobj.exists():
+ if unresolved not in result:
+ result.append(unresolved)
+ try:
+ resolved = Path(p).resolve().as_posix()
+ if resolved not in result:
+ result.append(resolved)
+ except FileNotFoundError:
+ pass
+ return tuple(result)
+
+ def get_compiler_dirs(self, env, name):
+ '''
+ Get dirs from the compiler, either `libraries:` or `programs:`
+ '''
+ stdo = self._get_search_dirs(env)
+ for line in stdo.split('\n'):
+ if line.startswith(name + ':'):
+ return self._split_fetch_real_dirs(line.split('=', 1)[1])
+ return ()
+
+
class GnuCompiler(GnuLikeCompiler):
"""
GnuCompiler represents an actual GCC in its many incarnations.
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 718dbdf..16269be 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -370,9 +370,11 @@ class VisualStudioLikeCPPCompilerMixin:
'vc++11': (True, 11),
'vc++14': (True, 14),
'vc++17': (True, 17),
+ 'vc++latest': (True, "latest"),
'c++11': (False, 11),
'c++14': (False, 14),
'c++17': (False, 17),
+ 'c++latest': (False, "latest"),
}
def get_option_link_args(self, options):
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 08e8827..1a397c7 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -433,6 +433,7 @@ class CoreData:
self.builtins['libdir'].value = 'lib'
def sanitize_prefix(self, prefix):
+ prefix = os.path.expanduser(prefix)
if not os.path.isabs(prefix):
raise MesonException('prefix value {!r} must be an absolute path'
''.format(prefix))
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
index f7b107c..223e6dc 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -460,12 +460,12 @@ class LLVMDependency(ExternalDependency):
methods = cls._process_method_kw(kwargs)
candidates = []
- if DependencyMethods.CMAKE in methods:
- candidates.append(functools.partial(LLVMDependencyCMake, env, kwargs))
-
if DependencyMethods.CONFIG_TOOL in methods:
candidates.append(functools.partial(LLVMDependencyConfigTool, env, kwargs))
+ if DependencyMethods.CMAKE in methods:
+ candidates.append(functools.partial(LLVMDependencyCMake, env, kwargs))
+
return candidates
@staticmethod
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index 03c6346..011ab5d 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -340,6 +340,10 @@ This is probably wrong, it should always point to the native compiler.''' % evar
command = os.environ.get(evar)
if command is not None:
command = shlex.split(command)
+
+ # Do not return empty or blank string entries
+ if command is not None and (len(command) == 0 or len(command[0].strip()) == 0):
+ return None
return command
class Directories:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 0cf511f..a47208d 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -376,7 +376,6 @@ class Environment:
def __init__(self, source_dir, build_dir, options):
self.source_dir = source_dir
self.build_dir = build_dir
-
# Do not try to create build directories when build_dir is none.
# This reduced mode is used by the --buildoptions introspector
if build_dir is not None:
@@ -910,7 +909,7 @@ class Environment:
return PathScaleFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'PGI Compilers' in out:
- if self.machine[for_machine].is_darwin():
+ if self.machines[for_machine].is_darwin():
compiler_type = CompilerType.PGI_OSX
elif self.machines[for_machine].is_windows():
compiler_type = CompilerType.PGI_WIN
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index f5bb4e5..a20dcd5 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -3853,6 +3853,23 @@ different subdirectory.
for_machine = self.machine_from_native_kwarg(kwargs)
self.add_project_arguments(node, self.build.projects_link_args[for_machine], args, kwargs)
+ def warn_about_builtin_args(self, args):
+ warnargs = ('/W1', '/W2', '/W3', '/W4', '/Wall', '-Wall', '-Wextra', '-Wpedantic')
+ optargs = ('-O0', '-O2', '-O3', '-Os', '/O1', '/O2', '/Os')
+ for arg in args:
+ if arg in warnargs:
+ mlog.warning("Consider using the builtin warning_level option instead of adding warning flags by hand.")
+ elif arg in optargs:
+ mlog.warning('Consider using the builtin optimization level rather than adding flags by hand.')
+ elif arg == '-g':
+ mlog.warning('Consider using the builtin debug option rather than adding flags by hand.')
+ elif arg == '-pipe':
+ mlog.warning("You don't need to add -pipe, Meson will use it automatically when it is available.")
+ elif arg.startswith('-fsanitize'):
+ mlog.warning('Consider using the builtin option for sanitizers rather than adding flags by hand.')
+ elif arg.startswith('-std=') or arg.startswith('/std:'):
+ mlog.warning('Consider using the builtin option for language standard version rather than adding flags by hand.')
+
def add_global_arguments(self, node, argsdict, args, kwargs):
if self.is_subproject():
msg = 'Function \'{}\' cannot be used in subprojects because ' \
@@ -3881,6 +3898,8 @@ different subdirectory.
if 'language' not in kwargs:
raise InvalidCode('Missing language definition in {}'.format(node.func_name))
+ self.warn_about_builtin_args(args)
+
for lang in mesonlib.stringlistify(kwargs['language']):
lang = lang.lower()
argsdict[lang] = argsdict.get(lang, []) + args
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index b700b00..e81a8e1 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -123,6 +123,8 @@ def list_installed(installdata):
res[path] = os.path.join(installdata.prefix, installdir, os.path.basename(path))
for path, installpath, _ in installdata.man:
res[path] = os.path.join(installdata.prefix, installpath)
+ for path, installpath, _, _ in installdata.install_subdirs:
+ res[path] = os.path.join(installdata.prefix, installpath)
return res
def list_targets_from_source(intr: IntrospectionInterpreter):
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index efc3218..7cf46f7 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -23,7 +23,7 @@ from . import get_include_args
from . import ModuleReturnValue
from . import ExtensionModule
from ..interpreter import CustomTargetHolder
-from ..interpreterbase import permittedKwargs, FeatureNewKwargs
+from ..interpreterbase import permittedKwargs, FeatureNewKwargs, flatten
from ..dependencies import ExternalProgram
class ResourceCompilerType(enum.Enum):
@@ -78,7 +78,7 @@ class WindowsModule(ExtensionModule):
@FeatureNewKwargs('windows.compile_resources', '0.47.0', ['depend_files', 'depends'])
@permittedKwargs({'args', 'include_directories', 'depend_files', 'depends'})
def compile_resources(self, state, args, kwargs):
- extra_args = mesonlib.stringlistify(kwargs.get('args', []))
+ extra_args = mesonlib.stringlistify(flatten(kwargs.get('args', [])))
wrc_depend_files = extract_as_list(kwargs, 'depend_files', pop = True)
wrc_depends = extract_as_list(kwargs, 'depends', pop = True)
for d in wrc_depends:
diff --git a/mesonbuild/scripts/dist.py b/mesonbuild/scripts/dist.py
index 47fde23..1a62c70 100644
--- a/mesonbuild/scripts/dist.py
+++ b/mesonbuild/scripts/dist.py
@@ -144,11 +144,15 @@ def create_dist_hg(dist_name, src_root, bld_root, dist_sub, dist_scripts):
return (xzname, )
-def check_dist(packagename, meson_command):
+def check_dist(packagename, meson_command, privdir):
print('Testing distribution package %s' % packagename)
- unpackdir = tempfile.mkdtemp()
- builddir = tempfile.mkdtemp()
- installdir = tempfile.mkdtemp()
+ unpackdir = os.path.join(privdir, 'dist-unpack')
+ builddir = os.path.join(privdir, 'dist-build')
+ installdir = os.path.join(privdir, 'dist-install')
+ for p in (unpackdir, builddir, installdir):
+ if os.path.exists(p):
+ shutil.rmtree(p)
+ os.mkdir(p)
ninja_bin = detect_ninja()
try:
tf = tarfile.open(packagename)
@@ -200,7 +204,7 @@ def run(args):
return 1
error_count = 0
for name in names:
- rc = check_dist(name, meson_command) # Check only one.
+ rc = check_dist(name, meson_command, priv_dir) # Check only one.
if rc == 0:
create_hash(name)
error_count += rc
diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py
index 85dfe99..3fe327f 100644
--- a/mesonbuild/scripts/meson_exe.py
+++ b/mesonbuild/scripts/meson_exe.py
@@ -78,6 +78,11 @@ def run_exe(exe):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
+
+ if p.returncode == 0xc0000135:
+ # STATUS_DLL_NOT_FOUND on Windows indicating a common problem that is otherwise hard to diagnose
+ raise FileNotFoundError('Missing DLLs on calling {!r}'.format(exe.name))
+
if exe.capture and p.returncode == 0:
with open(exe.capture, 'wb') as output:
output.write(stdout)
diff --git a/run_project_tests.py b/run_project_tests.py
index 3bd3253..154da00 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -803,6 +803,8 @@ def check_format():
for (root, _, files) in os.walk('.'):
if '.dub' in root: # external deps are here
continue
+ if '.pytest_cache' in root:
+ continue
if 'meson-logs' in root or 'meson-private' in root:
continue
for fname in files:
@@ -870,6 +872,8 @@ if __name__ == '__main__':
choices=backendlist)
parser.add_argument('--failfast', action='store_true',
help='Stop running if test case fails')
+ parser.add_argument('--no-unittests', action='store_true',
+ help='Not used, only here to simplify run_tests.py')
parser.add_argument('--only', help='name of test(s) to run', nargs='+')
options = parser.parse_args()
setup_commands(options.backend)
diff --git a/run_tests.py b/run_tests.py
index f427736..051b91e 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -262,6 +262,7 @@ def main():
choices=backendlist)
parser.add_argument('--cross', default=False, dest='cross', action='store_true')
parser.add_argument('--failfast', action='store_true')
+ parser.add_argument('--no-unittests', action='store_true', default=False)
(options, _) = parser.parse_known_args()
# Enable coverage early...
enable_coverage = options.cov
@@ -273,6 +274,7 @@ def main():
returncode = 0
cross = options.cross
backend, _ = guess_backend(options.backend, shutil.which('msbuild'))
+ no_unittests = options.no_unittests
# Running on a developer machine? Be nice!
if not mesonlib.is_windows() and not mesonlib.is_haiku() and 'CI' not in os.environ:
os.nice(20)
@@ -314,12 +316,16 @@ def main():
returncode += subprocess.call(cmd, env=env)
if options.failfast and returncode != 0:
return returncode
- cmd = mesonlib.python_command + ['run_unittests.py', '-v']
- if options.failfast:
- cmd += ['--failfast']
- returncode += subprocess.call(cmd, env=env)
- if options.failfast and returncode != 0:
- return returncode
+ if no_unittests:
+ print('Skipping all unit tests.')
+ returncode = 0
+ else:
+ cmd = mesonlib.python_command + ['run_unittests.py', '-v']
+ if options.failfast:
+ cmd += ['--failfast']
+ returncode += subprocess.call(cmd, env=env)
+ if options.failfast and returncode != 0:
+ return returncode
cmd = mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:]
returncode += subprocess.call(cmd, env=env)
else:
diff --git a/run_unittests.py b/run_unittests.py
index 602c6b7..33174b1 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1221,7 +1221,7 @@ class BasePlatformTests(unittest.TestCase):
os.environ.update(self.orig_env)
super().tearDown()
- def _run(self, command, workdir=None):
+ def _run(self, command, *, workdir=None, override_envvars=None):
'''
Run a command while printing the stdout and stderr to stdout,
and also return a copy of it
@@ -1229,8 +1229,14 @@ class BasePlatformTests(unittest.TestCase):
# If this call hangs CI will just abort. It is very hard to distinguish
# between CI issue and test bug in that case. Set timeout and fail loud
# instead.
+ if override_envvars is None:
+ env = None
+ else:
+ env = os.environ.copy()
+ env.update(override_envvars)
+
p = subprocess.run(command, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, env=os.environ.copy(),
+ stderr=subprocess.STDOUT, env=env,
universal_newlines=True, cwd=workdir, timeout=60 * 5)
print(p.stdout)
if p.returncode != 0:
@@ -1239,7 +1245,11 @@ class BasePlatformTests(unittest.TestCase):
raise subprocess.CalledProcessError(p.returncode, command, output=p.stdout)
return p.stdout
- def init(self, srcdir, extra_args=None, default_args=True, inprocess=False):
+ def init(self, srcdir, *,
+ extra_args=None,
+ default_args=True,
+ inprocess=False,
+ override_envvars=None):
self.assertPathExists(srcdir)
if extra_args is None:
extra_args = []
@@ -1254,7 +1264,13 @@ class BasePlatformTests(unittest.TestCase):
self.privatedir = os.path.join(self.builddir, 'meson-private')
if inprocess:
try:
+ if override_envvars is not None:
+ old_envvars = os.environ.copy()
+ os.environ.update(override_envvars)
(returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args)
+ if override_envvars is not None:
+ os.environ.clear()
+ os.environ.update(old_envvars)
if 'MESON_SKIP_TEST' in out:
raise unittest.SkipTest('Project requested skipping.')
if returncode != 0:
@@ -1274,7 +1290,7 @@ class BasePlatformTests(unittest.TestCase):
mesonbuild.mlog.log_file = None
else:
try:
- out = self._run(self.setup_command + args + extra_args)
+ out = self._run(self.setup_command + args + extra_args, override_envvars=override_envvars)
except unittest.SkipTest:
raise unittest.SkipTest('Project requested skipping: ' + srcdir)
except Exception:
@@ -1282,40 +1298,52 @@ class BasePlatformTests(unittest.TestCase):
raise
return out
- def build(self, target=None, extra_args=None):
+ def build(self, target=None, *, extra_args=None, override_envvars=None):
if extra_args is None:
extra_args = []
# Add arguments for building the target (if specified),
# and using the build dir (if required, with VS)
args = get_builddir_target_args(self.backend, self.builddir, target)
- return self._run(self.build_command + args + extra_args, workdir=self.builddir)
+ return self._run(self.build_command + args + extra_args, workdir=self.builddir, override_envvars=override_envvars)
- def clean(self):
+ def clean(self, *, override_envvars=None):
dir_args = get_builddir_target_args(self.backend, self.builddir, None)
- self._run(self.clean_command + dir_args, workdir=self.builddir)
+ self._run(self.clean_command + dir_args, workdir=self.builddir, override_envvars=override_envvars)
- def run_tests(self, inprocess=False):
+ def run_tests(self, *, inprocess=False, override_envvars=None):
if not inprocess:
- self._run(self.test_command, workdir=self.builddir)
+ self._run(self.test_command, workdir=self.builddir, override_envvars=override_envvars)
else:
- run_mtest_inprocess(['-C', self.builddir])
+ if override_envvars is not None:
+ old_envvars = os.environ.copy()
+ os.environ.update(override_envvars)
+ try:
+ run_mtest_inprocess(['-C', self.builddir])
+ finally:
+ if override_envvars is not None:
+ os.environ.clear()
+ os.environ.update(old_envvars)
- def install(self, *, use_destdir=True):
+ def install(self, *, use_destdir=True, override_envvars=None):
if self.backend is not Backend.ninja:
raise unittest.SkipTest('{!r} backend can\'t install files'.format(self.backend.name))
if use_destdir:
- os.environ['DESTDIR'] = self.installdir
- self._run(self.install_command, workdir=self.builddir)
+ destdir = {'DESTDIR': self.installdir}
+ if override_envvars is None:
+ override_envvars = destdir
+ else:
+ override_envvars.update(destdir)
+ self._run(self.install_command, workdir=self.builddir, override_envvars=override_envvars)
- def uninstall(self):
- self._run(self.uninstall_command, workdir=self.builddir)
+ def uninstall(self, *, override_envvars=None):
+ self._run(self.uninstall_command, workdir=self.builddir, override_envvars=override_envvars)
- def run_target(self, target):
+ def run_target(self, target, *, override_envvars=None):
'''
Run a Ninja target while printing the stdout and stderr to stdout,
and also return a copy of it
'''
- return self.build(target=target)
+ return self.build(target=target, override_envvars=override_envvars)
def setconf(self, arg, will_build=True):
if not isinstance(arg, list):
@@ -1498,7 +1526,7 @@ class AllPlatformTests(BasePlatformTests):
# This can just be a relative path, but we want to test
# that passing this as an absolute path also works
'--libdir=' + prefix + '/' + libdir]
- self.init(testdir, extra_args, default_args=False)
+ self.init(testdir, extra_args=extra_args, default_args=False)
opts = self.introspect('--buildoptions')
for opt in opts:
if opt['name'] == 'prefix':
@@ -1514,11 +1542,11 @@ class AllPlatformTests(BasePlatformTests):
testdir = os.path.join(self.common_test_dir, '1 trivial')
# libdir being inside prefix is ok
args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
- self.init(testdir, args)
+ self.init(testdir, extra_args=args)
self.wipe()
# libdir not being inside prefix is not ok
args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
- self.assertRaises(subprocess.CalledProcessError, self.init, testdir, args)
+ self.assertRaises(subprocess.CalledProcessError, self.init, testdir, extra_args=args)
self.wipe()
# libdir must be inside prefix even when set via mesonconf
self.init(testdir)
@@ -1558,7 +1586,7 @@ class AllPlatformTests(BasePlatformTests):
}
for prefix in expected:
args = ['--prefix', prefix]
- self.init(testdir, args, default_args=False)
+ self.init(testdir, extra_args=args, default_args=False)
opts = self.introspect('--buildoptions')
for opt in opts:
name = opt['name']
@@ -1597,7 +1625,7 @@ class AllPlatformTests(BasePlatformTests):
'sharedstatedir': '/var/state'},
}
for args in expected:
- self.init(testdir, args.split(), default_args=False)
+ self.init(testdir, extra_args=args.split(), default_args=False)
opts = self.introspect('--buildoptions')
for opt in opts:
name = opt['name']
@@ -1695,6 +1723,34 @@ class AllPlatformTests(BasePlatformTests):
self.assertPathListEqual(intro[0]['install_filename'], ['/usr/lib/libstat.a'])
self.assertPathListEqual(intro[1]['install_filename'], ['/usr/bin/prog' + exe_suffix])
+ def test_install_subdir_introspection(self):
+ '''
+ Test that the Meson introspection API also contains subdir install information
+ https://github.com/mesonbuild/meson/issues/5556
+ '''
+ testdir = os.path.join(self.common_test_dir, '63 install subdir')
+ self.init(testdir)
+ intro = self.introspect('--installed')
+ expected = {
+ 'sub2': 'share/sub2',
+ 'subdir/sub1': 'share/sub1',
+ 'subdir/sub_elided': 'share',
+ 'sub1': 'share/sub1',
+ 'sub/sub1': 'share/sub1',
+ 'sub_elided': 'share',
+ 'nested_elided/sub': 'share',
+ }
+
+ self.assertEqual(len(intro), len(expected))
+
+ # Convert expected to PurePath
+ expected_converted = {PurePath(os.path.join(testdir, key)): PurePath(os.path.join(self.prefix, val)) for key, val in expected.items()}
+ intro_converted = {PurePath(key): PurePath(val) for key, val in intro.items()}
+
+ for src, dst in expected_converted.items():
+ self.assertIn(src, intro_converted)
+ self.assertEqual(dst, intro_converted[src])
+
def test_install_introspection_multiple_outputs(self):
'''
Tests that the Meson introspection API exposes multiple install filenames correctly without crashing
@@ -1727,7 +1783,7 @@ class AllPlatformTests(BasePlatformTests):
def test_forcefallback(self):
testdir = os.path.join(self.unit_test_dir, '31 forcefallback')
- self.init(testdir, ['--wrap-mode=forcefallback'])
+ self.init(testdir, extra_args=['--wrap-mode=forcefallback'])
self.build()
self.run_tests()
@@ -2159,9 +2215,10 @@ class AllPlatformTests(BasePlatformTests):
# !, ^, *, and < confuse lcc preprocessor
value = 'spaces and fun@$&()-=_+{}[]:;>?,./~`'
for env_var in ['CPPFLAGS', 'CFLAGS']:
- os.environ[env_var] = '-D{}="{}"'.format(define, value)
- os.environ['LDFLAGS'] = '-DMESON_FAIL_VALUE=cflags-read'.format(define)
- self.init(testdir, ['-D{}={}'.format(define, value)])
+ env = {}
+ env[env_var] = '-D{}="{}"'.format(define, value)
+ env['LDFLAGS'] = '-DMESON_FAIL_VALUE=cflags-read'.format(define)
+ self.init(testdir, extra_args=['-D{}={}'.format(define, value)], override_envvars=env)
def test_custom_target_exe_data_deterministic(self):
testdir = os.path.join(self.common_test_dir, '114 custom target capture')
@@ -2514,9 +2571,8 @@ int main(int argc, char **argv) {
self.build_static_lib(cc, stlinker, source, objectfile, stlibfile, extra_args=['-DFOO_STATIC'])
self.build_shared_lib(cc, source, objectfile, shlibfile, impfile)
# Run test
- os.environ['PKG_CONFIG_LIBDIR'] = self.builddir
try:
- self.init(testdir)
+ self.init(testdir, override_envvars={'PKG_CONFIG_LIBDIR': self.builddir})
self.build()
self.run_tests()
finally:
@@ -2755,12 +2811,12 @@ int main(int argc, char **argv) {
name = os.path.basename(f.name)
with mock.patch.dict(os.environ, {'XDG_DATA_HOME': d}):
- self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
self.wipe()
with mock.patch.dict(os.environ, {'XDG_DATA_DIRS': d}):
os.environ.pop('XDG_DATA_HOME', None)
- self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
self.wipe()
with tempfile.TemporaryDirectory() as d:
@@ -2776,7 +2832,7 @@ int main(int argc, char **argv) {
with mock.patch.dict(os.environ):
os.environ.pop('XDG_DATA_HOME', None)
with mock.patch('mesonbuild.coredata.os.path.expanduser', lambda x: x.replace('~', d)):
- self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
self.wipe()
def test_compiler_run_command(self):
@@ -2871,9 +2927,8 @@ recommended as it is not supported on some platforms''')
# build user of library
self.new_builddir()
# replace is needed because meson mangles platform pathes passed via LDFLAGS
- os.environ["LDFLAGS"] = '-L{}'.format(libdir.replace('\\', '/'))
- self.init(os.path.join(testdirbase, 'exe'))
- del os.environ["LDFLAGS"]
+ self.init(os.path.join(testdirbase, 'exe'),
+ override_envvars={"LDFLAGS": '-L{}'.format(libdir.replace('\\', '/'))})
self.build()
self.assertBuildIsNoop()
@@ -3027,9 +3082,10 @@ recommended as it is not supported on some platforms''')
self.wipe()
# c_args value should be parsed with shlex
- self.init(testdir, extra_args=['-Dc_args=foo bar "one two"'])
+ self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"'])
obj = mesonbuild.coredata.load(self.builddir)
- self.assertEqual(obj.compiler_options.host['c_args'].value, ['foo', 'bar', 'one two'])
+ self.assertEqual(obj.compiler_options.host['c_args'].value, ['-Dfoo', '-Dbar', '-Dthird=one two'])
+
self.setconf('-Dc_args="foo bar" one two')
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.compiler_options.host['c_args'].value, ['foo bar', 'one', 'two'])
@@ -3040,21 +3096,21 @@ recommended as it is not supported on some platforms''')
self.init(testdir, extra_args=['--bindir=foo', '--bindir=bar',
'-Dbuildtype=plain', '-Dbuildtype=release',
'-Db_sanitize=address', '-Db_sanitize=thread',
- '-Dc_args=foo', '-Dc_args=bar'])
+ '-Dc_args=-Dfoo', '-Dc_args=-Dbar'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['bindir'].value, 'bar')
self.assertEqual(obj.builtins['buildtype'].value, 'release')
self.assertEqual(obj.base_options['b_sanitize'].value, 'thread')
- self.assertEqual(obj.compiler_options.host['c_args'].value, ['bar'])
+ self.assertEqual(obj.compiler_options.host['c_args'].value, ['-Dbar'])
self.setconf(['--bindir=bar', '--bindir=foo',
'-Dbuildtype=release', '-Dbuildtype=plain',
'-Db_sanitize=thread', '-Db_sanitize=address',
- '-Dc_args=bar', '-Dc_args=foo'])
+ '-Dc_args=-Dbar', '-Dc_args=-Dfoo'])
obj = mesonbuild.coredata.load(self.builddir)
self.assertEqual(obj.builtins['bindir'].value, 'foo')
self.assertEqual(obj.builtins['buildtype'].value, 'plain')
self.assertEqual(obj.base_options['b_sanitize'].value, 'address')
- self.assertEqual(obj.compiler_options.host['c_args'].value, ['foo'])
+ self.assertEqual(obj.compiler_options.host['c_args'].value, ['-Dfoo'])
self.wipe()
except KeyError:
# Ignore KeyError, it happens on CI for compilers that does not
@@ -3201,11 +3257,11 @@ recommended as it is not supported on some platforms''')
crossfile.flush()
self.meson_cross_file = crossfile.name
- os.environ['PKG_CONFIG_LIBDIR'] = os.path.join(testdir,
- 'native_pkgconfig')
- self.init(testdir, extra_args=['-Dstart_native=false'])
+ env = {'PKG_CONFIG_LIBDIR': os.path.join(testdir,
+ 'native_pkgconfig')}
+ self.init(testdir, extra_args=['-Dstart_native=false'], override_envvars=env)
self.wipe()
- self.init(testdir, extra_args=['-Dstart_native=true'])
+ self.init(testdir, extra_args=['-Dstart_native=true'], override_envvars=env)
def __reconfigure(self, change_minor=False):
# Set an older version to force a reconfigure from scratch
@@ -3342,7 +3398,7 @@ recommended as it is not supported on some platforms''')
for entry in res:
name = entry['name']
- self.assertEquals(entry['subproject'], expected[name])
+ self.assertEqual(entry['subproject'], expected[name])
def test_introspect_projectinfo_subproject_dir(self):
testdir = os.path.join(self.common_test_dir, '79 custom subproject dir')
@@ -3712,7 +3768,12 @@ class FailureTests(BasePlatformTests):
super().tearDown()
windows_proof_rmtree(self.srcdir)
- def assertMesonRaises(self, contents, match, extra_args=None, langs=None, meson_version=None, options=None):
+ def assertMesonRaises(self, contents, match, *,
+ extra_args=None,
+ langs=None,
+ meson_version=None,
+ options=None,
+ override_envvars=None):
'''
Assert that running meson configure on the specified @contents raises
a error message matching regex @match.
@@ -3730,11 +3791,17 @@ class FailureTests(BasePlatformTests):
if options is not None:
with open(self.moptions, 'w') as f:
f.write(options)
+ o = {'MESON_FORCE_BACKTRACE': '1'}
+ if override_envvars is None:
+ override_envvars = o
+ else:
+ override_envvars.update(o)
# Force tracebacks so we can detect them properly
- os.environ['MESON_FORCE_BACKTRACE'] = '1'
with self.assertRaisesRegex(MesonException, match, msg=contents):
# Must run in-process or we'll get a generic CalledProcessError
- self.init(self.srcdir, extra_args=extra_args, inprocess=True)
+ self.init(self.srcdir, extra_args=extra_args,
+ inprocess=True,
+ override_envvars = override_envvars)
def obtainMesonOutput(self, contents, match, extra_args, langs, meson_version=None):
if langs is None:
@@ -3844,9 +3911,9 @@ class FailureTests(BasePlatformTests):
def test_boost_BOOST_ROOT_dependency(self):
# Test BOOST_ROOT; can be run even if Boost is found or not
- os.environ['BOOST_ROOT'] = 'relative/path'
self.assertMesonRaises("dependency('boost')",
- "(BOOST_ROOT.*absolute|{})".format(self.dnf))
+ "(BOOST_ROOT.*absolute|{})".format(self.dnf),
+ override_envvars = {'BOOST_ROOT': 'relative/path'})
def test_dependency_invalid_method(self):
code = '''zlib_dep = dependency('zlib', required : false)
@@ -3905,9 +3972,8 @@ class FailureTests(BasePlatformTests):
Test exit status on python exception
'''
tdir = os.path.join(self.unit_test_dir, '21 exit status')
- os.environ['MESON_UNIT_TEST'] = '1'
with self.assertRaises(subprocess.CalledProcessError) as cm:
- self.init(tdir, inprocess=False)
+ self.init(tdir, inprocess=False, override_envvars = {'MESON_UNIT_TEST': '1'})
self.assertEqual(cm.exception.returncode, 2)
self.wipe()
@@ -4178,11 +4244,10 @@ class DarwinTests(BasePlatformTests):
# to ascertain that Meson does not call install_name_tool
# with duplicate -delete_rpath arguments, which would
# lead to erroring out on installation
- os.environ["LDFLAGS"] = "-Wl,-rpath,/foo/bar"
- self.init(testdir)
+ env = {"LDFLAGS": "-Wl,-rpath,/foo/bar"}
+ self.init(testdir, override_envvars=env)
self.build()
self.install()
- del os.environ["LDFLAGS"]
@unittest.skipUnless(not is_windows(), "requires something Unix-like")
@@ -4265,13 +4330,13 @@ class LinuxlikeTests(BasePlatformTests):
privatedir1 = self.privatedir
self.new_builddir()
- os.environ['PKG_CONFIG_LIBDIR'] = privatedir1
testdir = os.path.join(self.common_test_dir, '48 pkgconfig-gen', 'dependencies')
- self.init(testdir)
+ self.init(testdir, override_envvars={'PKG_CONFIG_LIBDIR': privatedir1})
privatedir2 = self.privatedir
- os.environ['PKG_CONFIG_LIBDIR'] = os.pathsep.join([privatedir1, privatedir2])
- self._run(['pkg-config', 'dependency-test', '--validate'])
+ os.environ
+ env = {'PKG_CONFIG_LIBDIR': os.pathsep.join([privatedir1, privatedir2])}
+ self._run(['pkg-config', 'dependency-test', '--validate'], override_envvars=env)
# pkg-config strips some duplicated flags so we have to parse the
# generated file ourself.
@@ -4297,14 +4362,14 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(len(expected), matched_lines)
cmd = ['pkg-config', 'requires-test']
- out = self._run(cmd + ['--print-requires']).strip().split('\n')
+ out = self._run(cmd + ['--print-requires'], override_envvars=env).strip().split('\n')
if not is_openbsd():
self.assertEqual(sorted(out), sorted(['libexposed', 'libfoo >= 1.0', 'libhello']))
else:
self.assertEqual(sorted(out), sorted(['libexposed', 'libfoo>=1.0', 'libhello']))
cmd = ['pkg-config', 'requires-private-test']
- out = self._run(cmd + ['--print-requires-private']).strip().split('\n')
+ out = self._run(cmd + ['--print-requires-private'], override_envvars=env).strip().split('\n')
if not is_openbsd():
self.assertEqual(sorted(out), sorted(['libexposed', 'libfoo >= 1.0', 'libhello']))
else:
@@ -4363,7 +4428,7 @@ class LinuxlikeTests(BasePlatformTests):
qt4 = subprocess.call(['pkg-config', '--exists', 'QtCore'])
qt5 = subprocess.call(['pkg-config', '--exists', 'Qt5Core'])
testdir = os.path.join(self.framework_test_dir, '4 qt')
- self.init(testdir, ['-Dmethod=pkg-config'])
+ self.init(testdir, extra_args=['-Dmethod=pkg-config'])
# Confirm that the dependency was found with pkg-config
mesonlog = self.get_meson_log()
if qt4 == 0:
@@ -4381,7 +4446,7 @@ class LinuxlikeTests(BasePlatformTests):
raise unittest.SkipTest('-fsanitize=address is not supported on OpenBSD')
testdir = os.path.join(self.framework_test_dir, '7 gnome')
- self.init(testdir, ['-Db_sanitize=address', '-Db_lundef=false'])
+ self.init(testdir, extra_args=['-Db_sanitize=address', '-Db_lundef=false'])
self.build()
def test_qt5dependency_qmake_detection(self):
@@ -4398,7 +4463,7 @@ class LinuxlikeTests(BasePlatformTests):
raise unittest.SkipTest('Qmake found, but it is not for Qt 5.')
# Disable pkg-config codepath and force searching with qmake/qmake-qt5
testdir = os.path.join(self.framework_test_dir, '4 qt')
- self.init(testdir, ['-Dmethod=qmake'])
+ self.init(testdir, extra_args=['-Dmethod=qmake'])
# Confirm that the dependency was found with qmake
mesonlog = self.get_meson_log()
self.assertRegex('\n'.join(mesonlog),
@@ -4463,9 +4528,10 @@ class LinuxlikeTests(BasePlatformTests):
an ordinary test case because it needs the environment to be set.
'''
Oflag = '-O3'
- os.environ['CFLAGS'] = os.environ['CXXFLAGS'] = Oflag
+ env = {'CFLAGS': Oflag,
+ 'CXXFLAGS': Oflag}
testdir = os.path.join(self.common_test_dir, '40 has function')
- self.init(testdir)
+ self.init(testdir, override_envvars=env)
cmds = self.get_meson_log_compiler_checks()
for cmd in cmds:
if cmd[0] == 'ccache':
@@ -4493,7 +4559,7 @@ class LinuxlikeTests(BasePlatformTests):
if (compiler.get_id() == 'gcc' and '2a' in v and version_compare(compiler.version, '<8.0.0')):
continue
std_opt = '{}={}'.format(lang_std, v)
- self.init(testdir, ['-D' + std_opt])
+ self.init(testdir, extra_args=['-D' + std_opt])
cmd = self.get_compdb()[0]['command']
# c++03 and gnu++03 are not understood by ICC, don't try to look for them
skiplist = frozenset([
@@ -4511,11 +4577,17 @@ class LinuxlikeTests(BasePlatformTests):
# Check that an invalid std option in CFLAGS/CPPFLAGS fails
# Needed because by default ICC ignores invalid options
cmd_std = '-std=FAIL'
- env_flags = p.upper() + 'FLAGS'
- os.environ[env_flags] = cmd_std
+ if p == 'c':
+ env_flag_name = 'CFLAGS'
+ elif p == 'cpp':
+ env_flag_name = 'CXXFLAGS'
+ else:
+ raise NotImplementedError('Language {} not defined.'.format(p))
+ env = {}
+ env[env_flag_name] = cmd_std
with self.assertRaises((subprocess.CalledProcessError, mesonbuild.mesonlib.EnvironmentException),
msg='C compiler should have failed with -std=FAIL'):
- self.init(testdir)
+ self.init(testdir, override_envvars = env)
# ICC won't fail in the above because additional flags are needed to
# make unknown -std=... options errors.
self.build()
@@ -4764,8 +4836,7 @@ class LinuxlikeTests(BasePlatformTests):
@skipIfNoPkgconfig
def test_order_of_l_arguments(self):
testdir = os.path.join(self.unit_test_dir, '8 -L -l order')
- os.environ['PKG_CONFIG_PATH'] = testdir
- self.init(testdir)
+ self.init(testdir, override_envvars={'PKG_CONFIG_PATH': testdir})
# NOTE: .pc file has -Lfoo -lfoo -Lbar -lbar but pkg-config reorders
# the flags before returning them to -Lfoo -Lbar -lfoo -lbar
# but pkgconf seems to not do that. Sigh. Support both.
@@ -4846,7 +4917,7 @@ class LinuxlikeTests(BasePlatformTests):
raise unittest.SkipTest('-fsanitize=address is not supported on OpenBSD')
testdir = os.path.join(self.common_test_dir, '13 pch')
- self.init(testdir, ['-Db_sanitize=address'])
+ self.init(testdir, extra_args=['-Db_sanitize=address'])
self.build()
compdb = self.get_compdb()
for i in compdb:
@@ -4862,7 +4933,7 @@ class LinuxlikeTests(BasePlatformTests):
# We need to use llvm-cov instead of gcovr with clang
raise unittest.SkipTest('Coverage does not work with clang right now, help wanted!')
testdir = os.path.join(self.common_test_dir, '1 trivial')
- self.init(testdir, ['-Db_coverage=true'])
+ self.init(testdir, extra_args=['-Db_coverage=true'])
self.build()
self.run_tests()
self.run_target('coverage-html')
@@ -4892,7 +4963,7 @@ endian = 'little'
def test_reconfigure(self):
testdir = os.path.join(self.unit_test_dir, '13 reconfigure')
- self.init(testdir, ['-Db_coverage=true'], default_args=False)
+ self.init(testdir, extra_args=['-Db_coverage=true'], default_args=False)
self.build('reconfigure')
def test_vala_generated_source_buildir_inside_source_tree(self):
@@ -4923,11 +4994,15 @@ endian = 'little'
also tested.
'''
testdir = os.path.join(self.framework_test_dir, '7 gnome')
- os.environ['MESON_UNIT_TEST_PRETEND_GLIB_OLD'] = "1"
mesonbuild.modules.gnome.native_glib_version = '2.20'
- self.init(testdir, inprocess=True)
- self.build()
- mesonbuild.modules.gnome.native_glib_version = None
+ env = {'MESON_UNIT_TEST_PRETEND_GLIB_OLD': "1"}
+ try:
+ self.init(testdir,
+ inprocess=True,
+ override_envvars=env)
+ self.build(override_envvars=env)
+ finally:
+ mesonbuild.modules.gnome.native_glib_version = None
@skipIfNoPkgconfig
def test_pkgconfig_usage(self):
@@ -4938,23 +5013,24 @@ endian = 'little'
stderr=subprocess.DEVNULL) != 0:
raise unittest.SkipTest('Glib 2.0 dependency not available.')
with tempfile.TemporaryDirectory() as tempdirname:
- self.init(testdir1, ['--prefix=' + tempdirname, '--libdir=lib'], default_args=False)
+ self.init(testdir1, extra_args=['--prefix=' + tempdirname, '--libdir=lib'], default_args=False)
self.install(use_destdir=False)
shutil.rmtree(self.builddir)
os.mkdir(self.builddir)
pkg_dir = os.path.join(tempdirname, 'lib/pkgconfig')
self.assertTrue(os.path.exists(os.path.join(pkg_dir, 'libpkgdep.pc')))
lib_dir = os.path.join(tempdirname, 'lib')
- os.environ['PKG_CONFIG_PATH'] = pkg_dir
+ myenv = os.environ.copy()
+ myenv['PKG_CONFIG_PATH'] = pkg_dir
# Private internal libraries must not leak out.
- pkg_out = subprocess.check_output(['pkg-config', '--static', '--libs', 'libpkgdep'])
+ pkg_out = subprocess.check_output(['pkg-config', '--static', '--libs', 'libpkgdep'], env=myenv)
self.assertFalse(b'libpkgdep-int' in pkg_out, 'Internal library leaked out.')
# Dependencies must not leak to cflags when building only a shared library.
- pkg_out = subprocess.check_output(['pkg-config', '--cflags', 'libpkgdep'])
+ pkg_out = subprocess.check_output(['pkg-config', '--cflags', 'libpkgdep'], env=myenv)
self.assertFalse(b'glib' in pkg_out, 'Internal dependency leaked to headers.')
# Test that the result is usable.
- self.init(testdir2)
- self.build()
+ self.init(testdir2, override_envvars=myenv)
+ self.build(override_envvars=myenv)
myenv = os.environ.copy()
myenv['LD_LIBRARY_PATH'] = ':'.join([lib_dir, myenv.get('LD_LIBRARY_PATH', '')])
if is_cygwin():
@@ -4998,9 +5074,9 @@ endian = 'little'
# build user of library
pkg_dir = os.path.join(tempdirname, 'lib/pkgconfig')
- os.environ['PKG_CONFIG_PATH'] = pkg_dir
self.new_builddir()
- self.init(os.path.join(testdirbase, 'app'))
+ self.init(os.path.join(testdirbase, 'app'),
+ override_envvars={'PKG_CONFIG_PATH': pkg_dir})
self.build()
@skipIfNoPkgconfig
@@ -5105,16 +5181,16 @@ endian = 'little'
self.install(use_destdir=False)
## New builddir for the consumer
self.new_builddir()
- os.environ['LIBRARY_PATH'] = os.path.join(installdir, self.libdir)
- os.environ['PKG_CONFIG_PATH'] = os.path.join(installdir, self.libdir, 'pkgconfig')
+ env = {'LIBRARY_PATH': os.path.join(installdir, self.libdir),
+ 'PKG_CONFIG_PATH': os.path.join(installdir, self.libdir, 'pkgconfig')}
testdir = os.path.join(self.unit_test_dir, '40 external, internal library rpath', 'built library')
# install into installdir without using DESTDIR
self.prefix = self.installdir
- self.init(testdir)
+ self.init(testdir, override_envvars=env)
self.prefix = oldprefix
- self.build()
+ self.build(override_envvars=env)
# test uninstalled
- self.run_tests()
+ self.run_tests(override_envvars=env)
if not is_osx():
# Rest of the workflow only works on macOS
return
@@ -5127,10 +5203,10 @@ endian = 'little'
## New builddir for testing that DESTDIR is not added to install_name
self.new_builddir()
# install into installdir with DESTDIR
- self.init(testdir)
- self.build()
+ self.init(testdir, override_envvars=env)
+ self.build(override_envvars=env)
# test running after installation
- self.install()
+ self.install(override_envvars=env)
prog = self.installdir + os.path.join(self.prefix, 'bin', 'prog')
lib = self.installdir + os.path.join(self.prefix, 'lib', 'libbar_built.dylib')
for f in prog, lib:
@@ -5220,14 +5296,14 @@ endian = 'little'
def test_identity_cross(self):
testdir = os.path.join(self.unit_test_dir, '58 identity cross')
crossfile = tempfile.NamedTemporaryFile(mode='w')
- os.environ['CC'] = '"' + os.path.join(testdir, 'build_wrapper.py') + '"'
+ env = {'CC': '"' + os.path.join(testdir, 'build_wrapper.py') + '"'}
crossfile.write('''[binaries]
c = ['{0}']
'''.format(os.path.join(testdir, 'host_wrapper.py')))
crossfile.flush()
self.meson_cross_file = crossfile.name
# TODO should someday be explicit about build platform only here
- self.init(testdir)
+ self.init(testdir, override_envvars=env)
def should_run_cross_arm_tests():
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
@@ -5249,8 +5325,7 @@ class LinuxCrossArmTests(BasePlatformTests):
inspect the compiler database.
'''
testdir = os.path.join(self.common_test_dir, '3 static')
- os.environ['CFLAGS'] = '-DBUILD_ENVIRONMENT_ONLY'
- self.init(testdir)
+ self.init(testdir, override_envvars={'CFLAGS': '-DBUILD_ENVIRONMENT_ONLY'})
compdb = self.get_compdb()
self.assertNotIn('-DBUILD_ENVIRONMENT_ONLY', compdb[0]['command'])
@@ -5319,18 +5394,23 @@ class LinuxCrossMingwTests(BasePlatformTests):
# Change cross file to use a non-existing exe_wrapper and it should fail
self.meson_cross_file = os.path.join(testdir, 'broken-cross.txt')
# Force tracebacks so we can detect them properly
- os.environ['MESON_FORCE_BACKTRACE'] = '1'
+ env = {'MESON_FORCE_BACKTRACE': '1'}
with self.assertRaisesRegex(MesonException, 'exe_wrapper.*target.*use-exe-wrapper'):
# Must run in-process or we'll get a generic CalledProcessError
- self.init(testdir, extra_args='-Drun-target=false', inprocess=True)
+ self.init(testdir, extra_args='-Drun-target=false',
+ inprocess=True,
+ override_envvars=env)
with self.assertRaisesRegex(MesonException, 'exe_wrapper.*run target.*run-prog'):
# Must run in-process or we'll get a generic CalledProcessError
- self.init(testdir, extra_args='-Dcustom-target=false', inprocess=True)
- self.init(testdir, extra_args=['-Dcustom-target=false', '-Drun-target=false'])
+ self.init(testdir, extra_args='-Dcustom-target=false',
+ inprocess=True,
+ override_envvars=env)
+ self.init(testdir, extra_args=['-Dcustom-target=false', '-Drun-target=false'],
+ override_envvars=env)
self.build()
with self.assertRaisesRegex(MesonException, 'exe_wrapper.*PATH'):
# Must run in-process or we'll get a generic CalledProcessError
- self.run_tests(inprocess=True)
+ self.run_tests(inprocess=True, override_envvars=env)
@skipIfNoPkgconfig
def test_cross_pkg_config_option(self):
@@ -5361,7 +5441,7 @@ class PythonTests(BasePlatformTests):
# will also try 'python' as a fallback and use it if the major
# version matches
try:
- self.init(testdir, ['-Dpython=python2'])
+ self.init(testdir, extra_args=['-Dpython=python2'])
self.build()
self.run_tests()
except unittest.SkipTest:
@@ -5377,7 +5457,7 @@ class PythonTests(BasePlatformTests):
for py in ('pypy', 'pypy3'):
try:
- self.init(testdir, ['-Dpython=%s' % py])
+ self.init(testdir, extra_args=['-Dpython=%s' % py])
except unittest.SkipTest:
# Same as above, pypy2 and pypy3 are not expected to be present
# on the test system, the test project only raises in these cases
@@ -5391,13 +5471,13 @@ class PythonTests(BasePlatformTests):
# The test is configured to error out with MESON_SKIP_TEST
# in case it could not find python
with self.assertRaises(unittest.SkipTest):
- self.init(testdir, ['-Dpython=not-python'])
+ self.init(testdir, extra_args=['-Dpython=not-python'])
self.wipe()
# While dir is an external command on both Windows and Linux,
# it certainly isn't python
with self.assertRaises(unittest.SkipTest):
- self.init(testdir, ['-Dpython=dir'])
+ self.init(testdir, extra_args=['-Dpython=dir'])
self.wipe()
@@ -5801,7 +5881,7 @@ class NativeFileTests(BasePlatformTests):
if mesonbuild.environment.detect_msys2_arch():
f.write(r'@python3 {} %*'.format(filename))
else:
- f.write('@py -3 {} %*'.format(filename))
+ f.write('@{} {} %*'.format(sys.executable, filename))
return batfile
def helper_for_compiler(self, lang, cb, for_machine = MachineChoice.HOST):
@@ -6400,6 +6480,17 @@ def unset_envs():
def main():
unset_envs()
+ pytest_args = ['-n', 'auto', './run_unittests.py']
+ if shutil.which('pytest-3'):
+ return subprocess.run(['pytest-3'] + pytest_args).returncode
+ elif shutil.which('pytest'):
+ return subprocess.run(['pytest'] + pytest_args).returncode
+ try:
+ import pytest # noqa: F401
+ return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode
+ except ImportError:
+ pass
+ # All attempts at locating pytest failed, fall back to plain unittest.
cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
'TAPParserTests',
diff --git a/test cases/frameworks/15 llvm/meson.build b/test cases/frameworks/15 llvm/meson.build
index af94dae..4b2c88c 100644
--- a/test cases/frameworks/15 llvm/meson.build
+++ b/test cases/frameworks/15 llvm/meson.build
@@ -31,25 +31,29 @@ if not dep_tinfo.found()
dep_tinfo = cpp.find_library('tinfo', required: false)
endif
-foreach static : [true, false]
- llvm_dep = dependency(
- 'llvm',
- modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
- 'mcjit', 'nativecodegen', 'amdgpu'],
- required : false,
- static : static,
- )
- if llvm_dep.found()
- name = static ? 'static' : 'dynamic'
- executable(
- 'sum-@0@'.format(name),
- 'sum.c',
- dependencies : [
- llvm_dep, dep_tinfo,
- # zlib will be statically linked on windows
- dependency('zlib', required : host_machine.system() != 'windows'),
- meson.get_compiler('c').find_library('dl', required : false),
- ]
+foreach method : ['config-tool', 'cmake']
+ foreach static : [true, false]
+ message('Trying method @0@ for @1@ link'.format(method, static ? 'static' : 'dynamic'))
+ llvm_dep = dependency(
+ 'llvm',
+ modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
+ 'mcjit', 'nativecodegen', 'amdgpu'],
+ required : false,
+ static : static,
+ method : method,
)
- endif
+ if llvm_dep.found()
+ name = static ? 'static' : 'dynamic'
+ executable(
+ 'sum-@0@-@1@'.format(name, method),
+ 'sum.c',
+ dependencies : [
+ llvm_dep, dep_tinfo,
+ # zlib will be statically linked on windows
+ dependency('zlib', required : host_machine.system() != 'windows'),
+ meson.get_compiler('c').find_library('dl', required : false),
+ ]
+ )
+ endif
+ endforeach
endforeach
diff --git a/test cases/frameworks/23 hotdoc/installed_files.txt b/test cases/frameworks/23 hotdoc/installed_files.txt
index 296dcf6..82597a2 100644
--- a/test cases/frameworks/23 hotdoc/installed_files.txt
+++ b/test cases/frameworks/23 hotdoc/installed_files.txt
@@ -66,6 +66,15 @@ usr/share/doc/foobar/html/assets/js/search/indecision
usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-hello-world.fragment
usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/dumped.trie
usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/foo.html-FooIndecision.fragment
+usr/share/doc/foobar/html/assets/js/search/Subpages
+usr/share/doc/foobar/html/assets/js/search/foo
+usr/share/doc/foobar/html/assets/js/search/API
+usr/share/doc/foobar/html/assets/js/search/Reference
+usr/share/doc/foobar/html/assets/js/search/api
+usr/share/doc/foobar/html/assets/js/search/reference
+usr/share/doc/foobar/html/assets/js/search/subpages
+usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-subpages.fragment
+usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/c-index.html-subpages.fragment
usr/share/doc/foobar/html/assets/prism_components/prism-inform7.min.js
usr/share/doc/foobar/html/assets/prism_components/prism-pascal.min.js
usr/share/doc/foobar/html/assets/prism_components/prism-bro.js
diff --git a/test cases/windows/5 resources/res/meson.build b/test cases/windows/5 resources/res/meson.build
index 160d651..74e0778 100644
--- a/test cases/windows/5 resources/res/meson.build
+++ b/test cases/windows/5 resources/res/meson.build
@@ -2,7 +2,8 @@ win = import('windows')
res = win.compile_resources('myres.rc',
depend_files: 'sample.ico',
- include_directories : inc)
+ include_directories : inc,
+ args : [['-DFOO'], '-DBAR'])
# test that with MSVC tools, LIB/LINK invokes CVTRES with correct /MACHINE
static_library('reslib', res, 'dummy.c')