aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ciimage/Dockerfile4
-rw-r--r--data/macros.meson44
-rw-r--r--docs/markdown/D.md56
-rw-r--r--docs/markdown/Dependencies.md34
-rw-r--r--docs/markdown/Dlang-module.md43
-rw-r--r--docs/markdown/Reference-manual.md2
-rw-r--r--docs/markdown/Reference-tables.md2
-rw-r--r--docs/markdown/snippets/configure_file_overwrite_warning.md39
-rw-r--r--docs/sitemap.txt1
-rw-r--r--man/mesonconf.110
-rw-r--r--man/mesonintrospect.113
-rw-r--r--man/mesontest.113
-rw-r--r--man/wraptool.113
-rw-r--r--mesonbuild/backend/ninjabackend.py25
-rw-r--r--mesonbuild/dependencies/base.py166
-rw-r--r--mesonbuild/environment.py4
-rw-r--r--mesonbuild/interpreter.py26
-rw-r--r--mesonbuild/modules/dlang.py141
-rwxr-xr-xmesonconf.py20
-rwxr-xr-xmesonintrospect.py20
-rwxr-xr-xmesonrewriter.py29
-rwxr-xr-xmesontest.py22
-rwxr-xr-xrun_unittests.py17
-rw-r--r--setup.py12
-rw-r--r--test cases/common/16 configure file/meson.build25
-rw-r--r--test cases/common/16 configure file/subdir/meson.build19
-rw-r--r--test cases/common/205 static threads/lib1.c13
-rw-r--r--test cases/common/205 static threads/lib2.c5
-rw-r--r--test cases/common/205 static threads/meson.build13
-rw-r--r--test cases/common/205 static threads/prog.c6
-rw-r--r--test cases/common/206 dep order/lib1.c0
-rw-r--r--test cases/common/206 dep order/lib2.c0
-rw-r--r--test cases/common/206 dep order/meson.build8
-rw-r--r--test cases/common/206 dep order/myexe.c3
-rw-r--r--test cases/d/11 dub/meson.build23
-rw-r--r--test cases/d/11 dub/test.d14
-rwxr-xr-xwraptool.py23
37 files changed, 674 insertions, 234 deletions
diff --git a/ciimage/Dockerfile b/ciimage/Dockerfile
index 92f4cfc..c398fad 100644
--- a/ciimage/Dockerfile
+++ b/ciimage/Dockerfile
@@ -12,7 +12,9 @@ RUN apt-get -y update && apt-get -y upgrade \
&& apt-get -y install qt4-linguist-tools \
&& apt-get -y install python-dev \
&& apt-get -y install libomp-dev openssh-client \
-&& python3 -m pip install hotdoc codecov
+&& python3 -m pip install hotdoc codecov \
+&& dub fetch urld \
+&& dub build urld --compiler=gdc
# OpenSSH client is needed to run openmpi binaries.
diff --git a/data/macros.meson b/data/macros.meson
index 732b68d..4a8a3ca 100644
--- a/data/macros.meson
+++ b/data/macros.meson
@@ -1,30 +1,28 @@
%__meson %{_bindir}/meson
%__meson_wrap_mode nodownload
+%__meson_auto_features enabled
%meson \
- export CFLAGS="${CFLAGS:-%__global_cflags}" \
- export CXXFLAGS="${CXXFLAGS:-%__global_cxxflags}" \
- export FFLAGS="${FFLAGS:-%__global_fflags}" \
- export FCFLAGS="${FCFLAGS:-%__global_fcflags}" \
- export LDFLAGS="${LDFLAGS:-%__global_ldflags}" \
- %{__meson} \\\
- --buildtype=plain \\\
- --prefix=%{_prefix} \\\
- --libdir=%{_libdir} \\\
- --libexecdir=%{_libexecdir} \\\
- --bindir=%{_bindir} \\\
- --sbindir=%{_sbindir} \\\
- --includedir=%{_includedir} \\\
- --datadir=%{_datadir} \\\
- --mandir=%{_mandir} \\\
- --infodir=%{_infodir} \\\
- --localedir=%{_datadir}/locale \\\
- --sysconfdir=%{_sysconfdir} \\\
- --localstatedir=%{_localstatedir} \\\
- --sharedstatedir=%{_sharedstatedir} \\\
- --wrap-mode=%{__meson_wrap_mode} \\\
- %{_vpath_srcdir} %{_vpath_builddir} \\\
- %{nil}
+ %set_build_flags \
+ %{shrink:%{__meson} \
+ --buildtype=plain \
+ --prefix=%{_prefix} \
+ --libdir=%{_libdir} \
+ --libexecdir=%{_libexecdir} \
+ --bindir=%{_bindir} \
+ --sbindir=%{_sbindir} \
+ --includedir=%{_includedir} \
+ --datadir=%{_datadir} \
+ --mandir=%{_mandir} \
+ --infodir=%{_infodir} \
+ --localedir=%{_datadir}/locale \
+ --sysconfdir=%{_sysconfdir} \
+ --localstatedir=%{_localstatedir} \
+ --sharedstatedir=%{_sharedstatedir} \
+ --wrap-mode=%{__meson_wrap_mode} \
+ --auto-features=%{__meson_auto_features} \
+ %{_vpath_srcdir} %{_vpath_builddir} \
+ %{nil}}
%meson_build \
%ninja_build -C %{_vpath_builddir}
diff --git a/docs/markdown/D.md b/docs/markdown/D.md
index 7b0d485..15de2f7 100644
--- a/docs/markdown/D.md
+++ b/docs/markdown/D.md
@@ -5,7 +5,8 @@ short-description: Compiling D sources
# Compiling D applications
-Meson has support for compiling D programs. A minimal `meson.build` file for D looks like this:
+Meson has support for compiling D programs. A minimal `meson.build`
+file for D looks like this:
```meson
project('myapp', 'd')
@@ -15,8 +16,8 @@ executable('myapp', 'app.d')
## Compiling different versions
-If you are using the [version()](https://dlang.org/spec/version.html) feature for conditional compilation, you can use it using the `d_module_versions`
-target property:
+If you are using the [version()](https://dlang.org/spec/version.html) feature for conditional compilation,
+you can use it using the `d_module_versions` target property:
```meson
project('myapp', 'd')
executable('myapp', 'app.d', d_module_versions: ['Demo', 'FeatureA'])
@@ -24,10 +25,14 @@ executable('myapp', 'app.d', d_module_versions: ['Demo', 'FeatureA'])
## Using embedded unittests
-If you are using embedded [unittest functions](https://dlang.org/spec/unittest.html), your source code needs to be compiled twice, once in regular
-mode, and once with unittests active. This is done by setting the `d_unittest` target property to `true`.
-Meson will only ever pass the respective compiler's `-unittest` flag, and never have the compiler generate an empty main function.
-If you need that feature in a portable way, create an empty `main()` function for unittests yourself, since the GNU D compiler
+If you are using embedded [unittest functions](https://dlang.org/spec/unittest.html), your source code needs
+to be compiled twice, once in regular
+mode, and once with unittests active. This is done by setting the
+`d_unittest` target property to `true`.
+Meson will only ever pass the respective compiler's `-unittest` flag,
+and never have the compiler generate an empty main function.
+If you need that feature in a portable way, create an empty `main()`
+function for unittests yourself, since the GNU D compiler
does not have this feature.
This is an example for using D unittests with Meson:
@@ -43,8 +48,10 @@ test('myapptest', test_exe)
# Compiling D libraries and installing them
-Building D libraries is a straightforward process, not different from how C libraries are built in Meson. You should generate a pkg-config file
-and install it, in order to make other software on the system find the dependency once it is installed.
+Building D libraries is a straightforward process, not different from
+how C libraries are built in Meson. You should generate a pkg-config
+file and install it, in order to make other software on the system
+find the dependency once it is installed.
This is an example on how to build a D shared library:
```meson
@@ -71,12 +78,17 @@ pkgc.generate(name: 'mylib',
install_subdir('src/mylib/', install_dir: 'include/d/mylib/')
```
-It is important to make the D sources install in a subdirectory in the include path, in this case `/usr/include/d/mylib/mylib`.
-All D compilers include the `/usr/include/d` directory by default, and if your library would be installed into `/usr/include/d/mylib`, there
-is a high chance that, when you compile your project again on a machine where you installed it, the compiler will prefer the old installed include over
-the new version in the source tree, leading to very confusing errors.
-
-This is an example of how to use the D library we just built and installed in an application:
+It is important to make the D sources install in a subdirectory in the
+ include path, in this case `/usr/include/d/mylib/mylib`.
+All D compilers include the `/usr/include/d` directory by default, and
+ if your library would be installed into `/usr/include/d/mylib`, there
+is a high chance that, when you compile your project again on a
+machine where you installed it, the compiler will prefer the old
+installed include over the new version in the source tree, leading to
+very confusing errors.
+
+This is an example of how to use the D library we just built and
+installed in an application:
```meson
project('myapp', 'd')
@@ -85,5 +97,15 @@ myapp_src = ['app.d', 'alpha.d', 'beta.d']
executable('myapp', myapp_src, dependencies: [mylib_dep])
```
-Please keep in mind that the library and executable would both need to be built with the exact same D compiler and D compiler version. The D ABI is not
-stable across compilers and their versions, and mixing compilers will lead to problems.
+Please keep in mind that the library and executable would both need to
+be built with the exact same D compiler and D compiler version. The D
+ABI is not stable across compilers and their versions, and mixing
+compilers will lead to problems.
+
+# Integrating with DUB
+
+DUB is a fully integrated build system for D, but it is also a way to
+provide dependencies. Adding dependencies from the [D package registry](https://code.dlang.org/)
+is pretty straight forward. You can find how to do this in
+[Dependencies](Dependencies.md#Dub). You can also automatically
+generate a `dub.json` file as explained in [Dlang](Dlang-module.md#generatedubfile).
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index 3e4e5ad..7b4262d 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -109,6 +109,38 @@ object. Since they can be used interchangeably, the rest of the build
definitions do not need to care which one it is. Meson will take care
of all the work behind the scenes to make this work.
+# Dependency method
+
+You can use the keyword `method` to let meson know what method to use
+when searching for the dependency. The default value is `auto`.
+Aditional dependencies methods are `pkg-config`, `config-tool`,
+`system`, `sysconfig`, `qmake`, `extraframework` and `dub`.
+
+```meson
+cups_dep = dependency('cups', method : 'pkg-config')
+```
+
+### Some notes on Dub
+
+Please understand that meson is only able to find dependencies that
+exist in the local Dub repository. You need to manually fetch and
+build the target dependencies.
+
+For `urld`.
+```
+dub fetch urld
+dub build urld
+```
+
+Other thing you need to keep in mind is that both meson and Dub need
+to be using the same compiler. This can be achieved using Dub's
+`-compiler` argument and/or manually setting the `DC` environment
+variable when running meson.
+```
+dub build urld --compiler=dmd
+DC="dmd" meson builddir
+```
+
# Dependencies with custom lookup functionality
Some dependencies have specific detection logic.
@@ -280,7 +312,7 @@ The `language` keyword may used.
Python3 is handled specially by meson:
1. Meson tries to use `pkg-config`.
-1. If `pkg-config` fails meson uses a fallback:
+2. If `pkg-config` fails meson uses a fallback:
- On Windows the fallback is the current `python3` interpreter.
- On OSX the fallback is a framework dependency from `/Library/Frameworks`.
diff --git a/docs/markdown/Dlang-module.md b/docs/markdown/Dlang-module.md
new file mode 100644
index 0000000..ca9a381
--- /dev/null
+++ b/docs/markdown/Dlang-module.md
@@ -0,0 +1,43 @@
+# Dlang module
+
+This module provides tools related to the D programming language.
+
+## Usage
+
+To use this module, just do: **`dlang = import('dlang')`**.
+You can, of course, replace the name `dlang` with anything else.
+
+The module only exposes one fucntion, `generate_dub_file`, used to
+automatically generate Dub configuration files.
+
+### generate_dub_file()
+This method only has two required arguments, the project name and the
+source folder. You can pass other arguments with additional keywords,
+they will be automatically translated to json and added to the
+`dub.json` file.
+
+**Structure**
+```meson
+generate_dub_file("project name", "source/folder", key: "value" ...)
+```
+
+**Example**
+```meson
+dlang = import('dlang')
+dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(),
+ authors: 'Meson Team',
+ description: 'Test executable',
+ copyright: 'Copyright © 2018, Meson Team',
+ license: 'MIT',
+ sourceFiles: 'test.d',
+ targetType: 'executable',
+ dependencies: my_dep
+)
+```
+
+You can manually edit a meson generated `dub.json` file or provide a
+initial one. The module will only update the values specified in
+`generate_dub_file()`.
+
+Although not required, you will need to have a `description` and
+`license` if you want to publish the package in the [D package registry](https://code.dlang.org/). \ No newline at end of file
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index e3ae111..db8eed1 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -684,7 +684,7 @@ configuration as-is, which may be absolute, or relative to `prefix`.
[`install_dir` arguments](Installing.md) handles that as expected, but
if you need the absolute path to one of these e.g. to use in a define
etc., you should use `join_paths(get_option('prefix'),
-get_option('localstatedir')))`
+get_option('localstatedir'))`
For options of type `feature` a special object is returned instead of
a string. See [`feature` options](Build-options.md#features)
diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md
index 6486aa2..91a8e3c 100644
--- a/docs/markdown/Reference-tables.md
+++ b/docs/markdown/Reference-tables.md
@@ -53,6 +53,8 @@ set in the cross file.
| ppc64 | 64 bit PPC processors |
| e2k | MCST Elbrus processor |
| parisc | HP PA-RISC processor |
+| riscv32 | 32 bit RISC-V Open ISA|
+| riscv64 | 64 bit RISC-V Open ISA|
| sparc64 | SPARC v9 processor |
Any cpu family not listed in the above list is not guaranteed to
diff --git a/docs/markdown/snippets/configure_file_overwrite_warning.md b/docs/markdown/snippets/configure_file_overwrite_warning.md
new file mode 100644
index 0000000..550407d
--- /dev/null
+++ b/docs/markdown/snippets/configure_file_overwrite_warning.md
@@ -0,0 +1,39 @@
+## Meson warns if two calls to configure_file() write to the same file
+
+If two calls to [`configure_file()`](#Reference-manual.md#configure_file)
+write to the same file Meson will print a `WARNING:` message during
+configuration. For example:
+```meson
+project('configure_file', 'cpp')
+
+configure_file(
+ input: 'a.in',
+ output: 'out',
+ command: ['./foo.sh']
+ )
+configure_file(
+ input: 'a.in',
+ output: 'out',
+ command: ['./foo.sh']
+)
+
+```
+
+This will output:
+
+```
+The Meson build system
+Version: 0.47.0.dev1
+Source dir: /path/to/srctree
+Build dir: /path/to/buildtree
+Build type: native build
+Project name: configure_file
+Project version: undefined
+Build machine cpu family: x86_64
+Build machine cpu: x86_64
+Configuring out with command
+WARNING: Output file out for configure_file overwritten. First time written in line 3 now in line 8
+Configuring out with command
+Build targets in project: 0
+Found ninja-1.8.2 at /usr/bin/ninja
+```
diff --git a/docs/sitemap.txt b/docs/sitemap.txt
index 68f0a8f..2d43e18 100644
--- a/docs/sitemap.txt
+++ b/docs/sitemap.txt
@@ -40,6 +40,7 @@ index.md
RPM-module.md
Simd-module.md
Windows-module.md
+ Dlang-module.md
Java.md
Vala.md
D.md
diff --git a/man/mesonconf.1 b/man/mesonconf.1
deleted file mode 100644
index 5463c71..0000000
--- a/man/mesonconf.1
+++ /dev/null
@@ -1,10 +0,0 @@
-.TH MESONCONF "1" "July 2018" "mesonconf 0.47.0" "User Commands"
-.SH NAME
-mesonconf - a tool to configure Meson builds
-.SH DESCRIPTION
-
-This executable is deprecated and will be removed in the future. The
-functionality that was in this executable can be invoked via the main Meson
-command like this:
-
-.B meson configure <options>
diff --git a/man/mesonintrospect.1 b/man/mesonintrospect.1
deleted file mode 100644
index 5d3eb42..0000000
--- a/man/mesonintrospect.1
+++ /dev/null
@@ -1,13 +0,0 @@
-.TH MESONINTROSPECT "1" "July 2018" "mesonintrospect 0.47.0" "User Commands"
-.SH NAME
-mesonintrospect - a tool to extract information about a Meson build
-.SH DESCRIPTION
-
-This executable is deprecated and will be removed in the future. The
-functionality that was in this executable can be invoked via the main Meson
-command like this:
-
-.B meson introspect <options>
-
-.SH SEE ALSO
-http://mesonbuild.com/
diff --git a/man/mesontest.1 b/man/mesontest.1
deleted file mode 100644
index e231bf6..0000000
--- a/man/mesontest.1
+++ /dev/null
@@ -1,13 +0,0 @@
-.TH MESON "1" "July 2018" "meson 0.47.0" "User Commands"
-.SH NAME
-mesontest - test tool for the Meson build system
-.SH DESCRIPTION
-
-This executable is deprecated and will be removed in the future. The
-functionality that was in this executable can be invoked via the main Meson
-command like this:
-
-.B meson test <options>
-
-.SH SEE ALSO
-http://mesonbuild.com/
diff --git a/man/wraptool.1 b/man/wraptool.1
deleted file mode 100644
index 7895e39..0000000
--- a/man/wraptool.1
+++ /dev/null
@@ -1,13 +0,0 @@
-.TH WRAPTOOL "1" "July 2018" "meson 0.47.0" "User Commands"
-.SH NAME
-wraptool - source dependency downloader
-.SH DESCRIPTION
-
-This executable is deprecated and will be removed in the future. The
-functionality that was in this executable can be invoked via the main Meson
-command like this:
-
-.B meson wrap <options>
-
-.SH SEE ALSO
-http://wrapdb.mesonbuild.com/
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 09c4904..c248ae8 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -73,8 +73,8 @@ class NinjaBuildElement:
self.infilenames = [infilenames]
else:
self.infilenames = infilenames
- self.deps = set()
- self.orderdeps = set()
+ self.deps = OrderedSet()
+ self.orderdeps = OrderedSet()
self.elems = []
self.all_outputs = all_outputs
@@ -2623,25 +2623,32 @@ rule FORTRAN_DEP_HACK%s
dependencies = target.get_dependencies()
internal = self.build_target_link_arguments(linker, dependencies)
commands += internal
- # For 'automagic' deps: Boost and GTest. Also dependency('threads').
- # pkg-config puts the thread flags itself via `Cflags:`
- for d in target.external_deps:
- if d.need_threads():
- commands += linker.thread_link_flags(self.environment)
- elif d.need_openmp():
- commands += linker.openmp_flags()
# Only non-static built targets need link args and link dependencies
if not isinstance(target, build.StaticLibrary):
+ # For 'automagic' deps: Boost and GTest. Also dependency('threads').
+ # pkg-config puts the thread flags itself via `Cflags:`
+ need_threads = False
+ need_openmp = False
+
commands += target.link_args
# External deps must be last because target link libraries may depend on them.
for dep in target.get_external_deps():
# Extend without reordering or de-dup to preserve `-L -l` sets
# https://github.com/mesonbuild/meson/issues/1718
commands.extend_direct(dep.get_link_args())
+ need_threads |= dep.need_threads()
+ need_openmp |= dep.need_openmp()
for d in target.get_dependencies():
if isinstance(d, build.StaticLibrary):
for dep in d.get_external_deps():
+ need_threads |= dep.need_threads()
+ need_openmp |= dep.need_openmp()
commands.extend_direct(dep.get_link_args())
+ if need_openmp:
+ commands += linker.openmp_flags()
+ if need_threads:
+ commands += linker.thread_link_flags(self.environment)
+
# Add link args for c_* or cpp_* build options. Currently this only
# adds c_winlibs and cpp_winlibs when building for Windows. This needs
# to be after all internal and external libraries so that unresolved
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 0fe702f..864fd73 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -19,6 +19,7 @@ import copy
import os
import re
import stat
+import json
import shlex
import shutil
import textwrap
@@ -31,7 +32,6 @@ from ..compilers import clib_langs
from ..mesonlib import MesonException, OrderedSet
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify
-
# These must be defined in this file to avoid cyclical references.
packages = {}
_packages_accept_language = set()
@@ -59,6 +59,8 @@ class DependencyMethods(Enum):
CUPSCONFIG = 'cups-config'
PCAPCONFIG = 'pcap-config'
LIBWMFCONFIG = 'libwmf-config'
+ # Misc
+ DUB = 'dub'
class Dependency:
@@ -790,6 +792,162 @@ class PkgConfigDependency(ExternalDependency):
# a path rather than the raw dlname
return os.path.basename(dlname)
+class DubDependency(ExternalDependency):
+ class_dubbin = None
+
+ def __init__(self, name, environment, kwargs):
+ super().__init__('dub', environment, 'd', kwargs)
+ self.name = name
+ self.compiler = super().get_compiler()
+
+ if 'required' in kwargs:
+ self.required = kwargs.get('required')
+
+ if DubDependency.class_dubbin is None:
+ self.dubbin = self.check_dub()
+ DubDependency.class_dubbin = self.dubbin
+ else:
+ self.dubbin = DubDependency.class_dubbin
+
+ if not self.dubbin:
+ if self.required:
+ raise DependencyException('DUB not found.')
+ self.is_found = False
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
+ return
+
+ mlog.debug('Determining dependency {!r} with DUB executable '
+ '{!r}'.format(name, self.dubbin.get_path()))
+
+ # Ask dub for the package
+ ret, res = self._call_dubbin(['describe', name])
+
+ if ret != 0:
+ if self.required:
+ raise DependencyException('Dependency {!r} not found'.format(name))
+ self.is_found = False
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
+ return
+
+ j = json.loads(res)
+ comp = self.compiler.get_id().replace('llvm', 'ldc').replace('gcc', 'gdc')
+ for package in j['packages']:
+ if package['name'] == name:
+ if j['compiler'] != comp:
+ msg = ['Dependency', mlog.bold(name), 'found but it was compiled with']
+ msg += [mlog.bold(j['compiler']), 'and we are using', mlog.bold(comp)]
+ mlog.error(*msg)
+ if self.required:
+ raise DependencyException('Dependency {!r} not found'.format(name))
+ self.is_found = False
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
+ return
+
+ self.version = package['version']
+ self.pkg = package
+ break
+
+ # Check if package version meets the requirements
+ found_msg = ['Dependency', mlog.bold(name), 'found:']
+ if self.version_reqs is None:
+ self.is_found = True
+ else:
+ if not isinstance(self.version_reqs, (str, list)):
+ raise DependencyException('Version argument must be string or list.')
+ if isinstance(self.version_reqs, str):
+ self.version_reqs = [self.version_reqs]
+ (self.is_found, not_found, found) = \
+ version_compare_many(self.version, self.version_reqs)
+ if not self.is_found:
+ found_msg += [mlog.red('NO'),
+ 'found {!r} but need:'.format(self.version),
+ ', '.join(["'{}'".format(e) for e in not_found])]
+ if found:
+ found_msg += ['; matched:',
+ ', '.join(["'{}'".format(e) for e in found])]
+ if not self.silent:
+ mlog.log(*found_msg)
+ if self.required:
+ m = 'Invalid version of dependency, need {!r} {!r} found {!r}.'
+ raise DependencyException(m.format(name, not_found, self.version))
+ return
+
+ found_msg += [mlog.green('YES'), self.version]
+
+ if self.pkg['targetFileName'].endswith('.a'):
+ self.static = True
+
+ self.compile_args = []
+ for flag in self.pkg['dflags']:
+ self.link_args.append(flag)
+ for path in self.pkg['importPaths']:
+ self.compile_args.append('-I' + os.path.join(self.pkg['path'], path))
+
+ self.link_args = []
+ for flag in self.pkg['lflags']:
+ self.link_args.append(flag)
+
+ search_paths = []
+ search_paths.append(os.path.join(self.pkg['path'], self.pkg['targetPath']))
+ found, res = self.__search_paths(search_paths, self.pkg['targetFileName'])
+ for file in res:
+ self.link_args.append(file)
+
+ if not found:
+ if self.required:
+ raise DependencyException('Dependency {!r} not found'.format(name))
+ self.is_found = False
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
+ return
+
+ if not self.silent:
+ mlog.log(*found_msg)
+
+ def get_compiler(self):
+ return self.compiler
+
+ def __search_paths(self, search_paths, target_file):
+ found = False
+ res = []
+ if target_file == '':
+ return True, res
+ for path in search_paths:
+ if os.path.isdir(path):
+ for file in os.listdir(path):
+ if file == target_file:
+ res.append(os.path.join(path, file))
+ found = True
+ return found, res
+
+ def _call_dubbin(self, args, env=None):
+ p, out = Popen_safe(self.dubbin.get_command() + args, env=env)[0:2]
+ return p.returncode, out.strip()
+
+ def check_dub(self):
+ dubbin = ExternalProgram('dub', silent=True)
+ if dubbin.found():
+ try:
+ p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2]
+ if p.returncode != 0:
+ mlog.warning('Found dub {!r} but couldn\'t run it'
+ ''.format(' '.join(dubbin.get_command())))
+ # Set to False instead of None to signify that we've already
+ # searched for it and not found it
+ dubbin = False
+ except (FileNotFoundError, PermissionError):
+ dubbin = False
+ else:
+ dubbin = False
+ if dubbin:
+ mlog.log('Found DUB:', mlog.bold(dubbin.get_path()),
+ '(%s)' % out.strip())
+ else:
+ mlog.log('Found DUB:', mlog.red('NO'))
+ return dubbin
+
+ @staticmethod
+ def get_methods():
+ return [DependencyMethods.PKGCONFIG, DependencyMethods.DUB]
class ExternalProgram:
windows_exts = ('exe', 'msc', 'com', 'bat', 'cmd')
@@ -1097,6 +1255,7 @@ def find_external_dependency(name, env, kwargs):
raise DependencyException('Keyword "required" must be a boolean.')
if not isinstance(kwargs.get('method', ''), str):
raise DependencyException('Keyword "method" must be a string.')
+ method = kwargs.get('method', '')
lname = name.lower()
if lname in packages:
if lname not in _packages_accept_language and 'language' in kwargs:
@@ -1113,6 +1272,11 @@ def find_external_dependency(name, env, kwargs):
if 'language' in kwargs:
# Remove check when PkgConfigDependency supports language.
raise DependencyException('%s dependency does not accept "language" keyword argument' % (lname, ))
+ if 'dub' == method:
+ dubdep = DubDependency(name, env, kwargs)
+ if required and not dubdep.found():
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
+ return dubdep
pkg_exc = None
pkgdep = None
try:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 0aa0b32..be92bfd 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -84,6 +84,8 @@ known_cpu_families = (
'parisc',
'ppc',
'ppc64',
+ 'riscv32',
+ 'riscv64',
'sparc64',
'x86',
'x86_64'
@@ -465,6 +467,8 @@ This is probably wrong, it should always point to the native compiler.''' % evar
C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
'''
if self.is_cross_build() and want_cross:
+ if lang not in self.cross_info.config['binaries']:
+ raise EnvironmentException('{!r} compiler binary not defined in cross file'.format(lang))
compilers = mesonlib.stringlistify(self.cross_info.config['binaries'][lang])
# Ensure ccache exists and remove it if it doesn't
if compilers[0] == 'ccache':
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 2c54eae..cf2e826 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -92,12 +92,13 @@ class FeatureOptionHolder(InterpreterObject, ObjectHolder):
def auto_method(self, args, kwargs):
return self.held_object.is_auto()
-def extract_required_kwarg(kwargs):
+def extract_required_kwarg(kwargs, subproject):
val = kwargs.get('required', True)
disabled = False
required = False
feature = None
if isinstance(val, FeatureOptionHolder):
+ FeatureNew('User option "feature"', '0.47.0').use(subproject)
option = val.held_object
feature = val.name
if option.is_disabled():
@@ -376,6 +377,7 @@ class DependencyHolder(InterpreterObject, ObjectHolder):
self.methods.update({'found': self.found_method,
'type_name': self.type_name_method,
'version': self.version_method,
+ 'name': self.name_method,
'get_pkgconfig_variable': self.pkgconfig_method,
'get_configtool_variable': self.configtool_method,
'partial_dependency': self.partial_dependency_method,
@@ -398,6 +400,11 @@ class DependencyHolder(InterpreterObject, ObjectHolder):
def version_method(self, args, kwargs):
return self.held_object.get_version()
+ @noPosargs
+ @permittedKwargs({})
+ def name_method(self, args, kwargs):
+ return self.held_object.get_name()
+
@permittedKwargs({'define_variable'})
def pkgconfig_method(self, args, kwargs):
args = listify(args)
@@ -1418,7 +1425,7 @@ class CompilerHolder(InterpreterObject):
if not isinstance(libname, str):
raise InterpreterException('Library name not a string.')
- disabled, required, feature = extract_required_kwarg(kwargs)
+ disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
mlog.log('Library', mlog.bold(libname), 'skipped: feature', mlog.bold(feature), 'disabled')
lib = dependencies.ExternalLibrary(libname, None,
@@ -1868,6 +1875,7 @@ class Interpreter(InterpreterBase):
self.global_args_frozen = False # implies self.project_args_frozen
self.subprojects = {}
self.subproject_stack = []
+ self.configure_file_outputs = {}
# Passed from the outside, only used in subprojects.
if default_project_options:
self.default_project_options = default_project_options.copy()
@@ -2464,7 +2472,7 @@ external dependencies (including libraries) must go to "dependencies".''')
@permittedKwargs(permitted_kwargs['add_languages'])
@stringArgs
def func_add_languages(self, node, args, kwargs):
- disabled, required, feature = extract_required_kwarg(kwargs)
+ disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
for lang in sorted(args, key=compilers.sort_clink):
mlog.log('Compiler for language', mlog.bold(lang), 'skipped: feature', mlog.bold(feature), 'disabled')
@@ -2725,7 +2733,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if not args:
raise InterpreterException('No program name specified.')
- disabled, required, feature = extract_required_kwarg(kwargs)
+ disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
mlog.log('Program', mlog.bold(' '.join(args)), 'skipped: feature', mlog.bold(feature), 'disabled')
return ExternalProgramHolder(dependencies.NonExistingExternalProgram())
@@ -2840,7 +2848,7 @@ external dependencies (including libraries) must go to "dependencies".''')
name = args[0]
display_name = name if name else '(anonymous)'
- disabled, required, feature = extract_required_kwarg(kwargs)
+ disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
mlog.log('Dependency', mlog.bold(display_name), 'skipped: feature', mlog.bold(feature), 'disabled')
return DependencyHolder(NotFoundDependency(self.environment), self.subproject)
@@ -3453,8 +3461,16 @@ root and issuing %s.
raise InterpreterException('@INPUT@ used as command argument, but no input file specified.')
# Validate output
output = kwargs['output']
+ ofile_rpath = os.path.join(self.subdir, output)
if not isinstance(output, str):
raise InterpreterException('Output file name must be a string')
+ if ofile_rpath in self.configure_file_outputs:
+ mesonbuildfile = os.path.join(self.subdir, 'meson.build')
+ current_call = "{}:{}".format(mesonbuildfile, self.current_lineno)
+ first_call = "{}:{}".format(mesonbuildfile, self.configure_file_outputs[ofile_rpath])
+ mlog.warning('Output file', mlog.bold(ofile_rpath, True), 'for configure_file() at', current_call, 'overwrites configure_file() output at', first_call)
+ else:
+ self.configure_file_outputs[ofile_rpath] = self.current_lineno
if ifile_abs:
values = mesonlib.get_filenames_templates_dict([ifile_abs], None)
outputs = mesonlib.substitute_values([output], values)
diff --git a/mesonbuild/modules/dlang.py b/mesonbuild/modules/dlang.py
new file mode 100644
index 0000000..d4f62e4
--- /dev/null
+++ b/mesonbuild/modules/dlang.py
@@ -0,0 +1,141 @@
+# Copyright 2018 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file contains the detection logic for external dependencies that
+# are UI-related.
+
+import json
+import os
+
+from . import ExtensionModule
+
+from .. import mlog
+
+from ..mesonlib import (
+ Popen_safe, MesonException
+)
+
+from ..dependencies.base import (
+ ExternalProgram, DubDependency
+)
+
+from ..interpreter import DependencyHolder
+
+class DlangModule(ExtensionModule):
+ class_dubbin = None
+ init_dub = False
+
+ def __init__(self, interpreter):
+ super().__init__(interpreter)
+ self.snippets.add('generate_dub_file')
+
+ def _init_dub(self):
+ if DlangModule.class_dubbin is None:
+ self.dubbin = DubDependency.class_dubbin
+ DlangModule.class_dubbin = self.dubbin
+ else:
+ self.dubbin = DlangModule.class_dubbin
+
+ if DlangModule.class_dubbin is None:
+ self.dubbin = self.check_dub()
+ DlangModule.class_dubbin = self.dubbin
+ else:
+ self.dubbin = DlangModule.class_dubbin
+
+ if not self.dubbin:
+ if not self.dubbin:
+ raise MesonException('DUB not found.')
+
+ def generate_dub_file(self, interpreter, state, args, kwargs):
+ if not DlangModule.init_dub:
+ self._init_dub()
+
+ if len(args) < 2:
+ raise MesonException('Missing arguments')
+
+ config = {
+ 'name': args[0]
+ }
+
+ config_path = os.path.join(args[1], 'dub.json')
+ if os.path.exists(config_path):
+ with open(config_path, 'r', encoding='utf8') as ofile:
+ try:
+ config = json.load(ofile)
+ except ValueError:
+ mlog.warning('Failed to load the data in dub.json')
+
+ warn_publishing = ['description', 'license']
+ for arg in warn_publishing:
+ if arg not in kwargs and \
+ arg not in config:
+ mlog.warning('Without', mlog.bold(arg), 'the DUB package can\'t be published')
+
+ for key, value in kwargs.items():
+ if key == 'dependencies':
+ config[key] = {}
+ if isinstance(value, list):
+ for dep in value:
+ if isinstance(dep, DependencyHolder):
+ name = dep.method_call('name', [], [])
+ ret, res = self._call_dubbin(['describe', name])
+ if ret == 0:
+ version = dep.method_call('version', [], [])
+ if version is None:
+ config[key][name] = ''
+ else:
+ config[key][name] = version
+ elif isinstance(value, DependencyHolder):
+ name = value.method_call('name', [], [])
+ ret, res = self._call_dubbin(['describe', name])
+ if ret == 0:
+ version = value.method_call('version', [], [])
+ if version is None:
+ config[key][name] = ''
+ else:
+ config[key][name] = version
+ else:
+ config[key] = value
+
+ with open(config_path, 'w', encoding='utf8') as ofile:
+ ofile.write(json.dumps(config, indent=4, ensure_ascii=False))
+
+ def _call_dubbin(self, args, env=None):
+ p, out = Popen_safe(self.dubbin.get_command() + args, env=env)[0:2]
+ return p.returncode, out.strip()
+
+ def check_dub(self):
+ dubbin = ExternalProgram('dub', silent=True)
+ if dubbin.found():
+ try:
+ p, out = Popen_safe(dubbin.get_command() + ['--version'])[0:2]
+ if p.returncode != 0:
+ mlog.warning('Found dub {!r} but couldn\'t run it'
+ ''.format(' '.join(dubbin.get_command())))
+ # Set to False instead of None to signify that we've already
+ # searched for it and not found it
+ dubbin = False
+ except (FileNotFoundError, PermissionError):
+ dubbin = False
+ else:
+ dubbin = False
+ if dubbin:
+ mlog.log('Found DUB:', mlog.bold(dubbin.get_path()),
+ '(%s)' % out.strip())
+ else:
+ mlog.log('Found DUB:', mlog.red('NO'))
+ return dubbin
+
+def initialize(*args, **kwargs):
+ return DlangModule(*args, **kwargs)
diff --git a/mesonconf.py b/mesonconf.py
deleted file mode 100755
index 894ec01..0000000
--- a/mesonconf.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2016 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-
-if __name__ == '__main__':
- sys.exit('Error: This executable is no more. Use "meson configure" instead.')
diff --git a/mesonintrospect.py b/mesonintrospect.py
deleted file mode 100755
index 9ef1535..0000000
--- a/mesonintrospect.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2016 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-
-if __name__ == '__main__':
- sys.exit('Error: This executable is no more. Use "meson introspect" instead.')
diff --git a/mesonrewriter.py b/mesonrewriter.py
deleted file mode 100755
index ef47e57..0000000
--- a/mesonrewriter.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2016 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This class contains the basic functionality needed to run any interpreter
-# or an interpreter-based tool.
-
-# This tool is used to manipulate an existing Meson build definition.
-#
-# - add a file to a target
-# - remove files from a target
-# - move targets
-# - reindent?
-
-import sys
-
-if __name__ == '__main__':
- sys.exit('Error: This executable is no more. Use "meson rewrite" instead.')
diff --git a/mesontest.py b/mesontest.py
deleted file mode 100755
index e973d56..0000000
--- a/mesontest.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2016-2017 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# A tool to run tests in many different ways.
-
-import sys
-
-if __name__ == '__main__':
- sys.exit('Error: This executable is no more. Use "meson test" instead.')
diff --git a/run_unittests.py b/run_unittests.py
index f4e95a3..912c843 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -2413,6 +2413,10 @@ recommended as it is not supported on some platforms''')
self.assertRegex(out, "WARNING:.*'FOO_BAR'.*nosubst-nocopy2.txt.in.*not present.*")
self.assertRegex(out, "WARNING:.*'empty'.*config.h.in.*not present.*")
self.assertRegex(out, "WARNING:.*empty configuration_data.*test.py.in")
+ # Warnings for configuration files that are overwritten.
+ self.assertRegex(out, "WARNING:.*\"double_output.txt\".*overwrites")
+ self.assertRegex(out, "WARNING:.*\"subdir.double_output2.txt\".*overwrites")
+ self.assertNotRegex(out, "WARNING:.*no_write_conflict.txt.*overwrites")
# No warnings about empty configuration data objects passed to files with substitutions
self.assertNotRegex(out, "WARNING:.*empty configuration_data.*nosubst-nocopy1.txt.in")
self.assertNotRegex(out, "WARNING:.*empty configuration_data.*nosubst-nocopy2.txt.in")
@@ -3583,6 +3587,19 @@ endian = 'little'
self.build()
self.run_tests()
+ def test_deterministic_dep_order(self):
+ '''
+ Test that the dependencies are always listed in a deterministic order.
+ '''
+ testdir = os.path.join(self.common_test_dir, '206 dep order')
+ self.init(testdir)
+ with open(os.path.join(self.builddir, 'build.ninja')) as bfile:
+ for line in bfile:
+ if 'build myexe:' in line or 'build myexe.exe:' in line:
+ self.assertIn('liblib1.a liblib2.a', line)
+ return
+ raise RuntimeError('Could not find the build rule')
+
@skipIfNoPkgconfig
def test_usage_external_library(self):
'''
diff --git a/setup.py b/setup.py
index bfa08df..8c267a3 100644
--- a/setup.py
+++ b/setup.py
@@ -71,17 +71,9 @@ setup(name='meson',
'mesonbuild.modules',
'mesonbuild.scripts',
'mesonbuild.wrap'],
- scripts=['meson.py',
- 'mesonconf.py',
- 'mesontest.py',
- 'mesonintrospect.py',
- 'wraptool.py'],
+ scripts=['meson.py'],
cmdclass={'install_scripts': install_scripts},
- data_files=[('share/man/man1', ['man/meson.1',
- 'man/mesonconf.1',
- 'man/mesonintrospect.1',
- 'man/mesontest.1',
- 'man/wraptool.1']),
+ data_files=[('share/man/man1', ['man/meson.1']),
('share/polkit-1/actions', ['data/com.mesonbuild.install.policy'])],
classifiers=['Development Status :: 5 - Production/Stable',
'Environment :: Console',
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 8c375c1..d7beeb1 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -193,15 +193,15 @@ configure_file(
configuration : configuration_data()
)
-# Test that passing an empty configuration_data() object to a file with
-# @FOO@ substitutions does not print the warning.
+# test that passing an empty configuration_data() object to a file with
+# @foo@ substitutions does not print the warning.
configure_file(
input: 'nosubst-nocopy2.txt.in',
output: 'nosubst-nocopy2.txt',
configuration : configuration_data()
)
-# Test that passing a configured file object to test() works, and that passing
+# test that passing a configured file object to test() works, and that passing
# an empty configuration_data() object to a file that leads to no substitutions
# prints a warning (see unit tests)
test_file = configure_file(
@@ -210,6 +210,25 @@ test_file = configure_file(
configuration: configuration_data()
)
+# Test that overwriting an existing file creates a warning.
+configure_file(
+ input: 'test.py.in',
+ output: 'double_output.txt',
+ configuration: conf
+)
+configure_file(
+ input: 'test.py.in',
+ output: 'double_output.txt',
+ configuration: conf
+)
+
+# Test that the same file name in a different subdir will not create a warning
+configure_file(
+ input: 'test.py.in',
+ output: 'no_write_conflict.txt',
+ configuration: conf
+)
+
test('configure-file', test_file)
cdata = configuration_data()
diff --git a/test cases/common/16 configure file/subdir/meson.build b/test cases/common/16 configure file/subdir/meson.build
index d802c1d..146b7b6 100644
--- a/test cases/common/16 configure file/subdir/meson.build
+++ b/test cases/common/16 configure file/subdir/meson.build
@@ -17,3 +17,22 @@ configure_file(input : '../dummy.dat',
output : 'config2-3.h',
command : [found_script, '@INPUT@', '@OUTPUT@'])
run_command(check_file, join_paths(meson.current_build_dir(), 'config2-3.h'))
+
+# Test that overwriting an existing file creates a warning.
+configure_file(
+ input: '../test.py.in',
+ output: 'double_output2.txt',
+ configuration: conf
+)
+configure_file(
+ input: '../test.py.in',
+ output: 'double_output2.txt',
+ configuration: conf
+)
+
+# Test that the same file name in a different subdir will not create a warning
+configure_file(
+ input: '../test.py.in',
+ output: 'no_write_conflict.txt',
+ configuration: conf
+)
diff --git a/test cases/common/205 static threads/lib1.c b/test cases/common/205 static threads/lib1.c
new file mode 100644
index 0000000..1aa786c
--- /dev/null
+++ b/test cases/common/205 static threads/lib1.c
@@ -0,0 +1,13 @@
+#if defined _WIN32
+#include<windows.h>
+#else
+#include<pthread.h>
+#endif
+
+void *f(void) {
+#if defined _WIN32
+ return CreateThread;
+#else
+ return pthread_create;
+#endif
+}
diff --git a/test cases/common/205 static threads/lib2.c b/test cases/common/205 static threads/lib2.c
new file mode 100644
index 0000000..e988814
--- /dev/null
+++ b/test cases/common/205 static threads/lib2.c
@@ -0,0 +1,5 @@
+extern void *f(void);
+
+void *g(void) {
+ return f();
+}
diff --git a/test cases/common/205 static threads/meson.build b/test cases/common/205 static threads/meson.build
new file mode 100644
index 0000000..4279200
--- /dev/null
+++ b/test cases/common/205 static threads/meson.build
@@ -0,0 +1,13 @@
+project('threads', 'c')
+
+thread_dep = dependency('threads')
+
+
+lib1 = static_library('lib1', 'lib1.c',
+ dependencies : thread_dep)
+
+lib2 = static_library('lib2', 'lib2.c',
+ link_with : lib1)
+
+executable('prog', 'prog.c',
+ link_with : lib2)
diff --git a/test cases/common/205 static threads/prog.c b/test cases/common/205 static threads/prog.c
new file mode 100644
index 0000000..14a7c76
--- /dev/null
+++ b/test cases/common/205 static threads/prog.c
@@ -0,0 +1,6 @@
+extern void *g(void);
+
+int main(void) {
+ g();
+ return 0;
+}
diff --git a/test cases/common/206 dep order/lib1.c b/test cases/common/206 dep order/lib1.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/206 dep order/lib1.c
diff --git a/test cases/common/206 dep order/lib2.c b/test cases/common/206 dep order/lib2.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/206 dep order/lib2.c
diff --git a/test cases/common/206 dep order/meson.build b/test cases/common/206 dep order/meson.build
new file mode 100644
index 0000000..17cf9df
--- /dev/null
+++ b/test cases/common/206 dep order/meson.build
@@ -0,0 +1,8 @@
+project('myexe', 'c')
+
+lib1 = static_library('lib1', 'lib1.c')
+lib2 = static_library('lib2', 'lib2.c')
+
+executable('myexe',
+ 'myexe.c',
+ link_with: [lib1, lib2])
diff --git a/test cases/common/206 dep order/myexe.c b/test cases/common/206 dep order/myexe.c
new file mode 100644
index 0000000..8f4c045
--- /dev/null
+++ b/test cases/common/206 dep order/myexe.c
@@ -0,0 +1,3 @@
+int main(int ac, char** av) {
+ return 0;
+}
diff --git a/test cases/d/11 dub/meson.build b/test cases/d/11 dub/meson.build
new file mode 100644
index 0000000..d852ca0
--- /dev/null
+++ b/test cases/d/11 dub/meson.build
@@ -0,0 +1,23 @@
+project('dub-example', 'd')
+
+dub_exe = find_program('dub', required : false)
+if not dub_exe.found()
+ error('MESON_SKIP_TEST: Dub not found')
+endif
+
+urld_dep = dependency('urld', method: 'dub')
+
+test_exe = executable('test-urld', 'test.d', dependencies: urld_dep)
+test('test urld', test_exe)
+
+# If you want meson to generate/update a dub.json file
+dlang = import('dlang')
+dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(),
+ authors: 'Meson Team',
+ description: 'Test executable',
+ copyright: 'Copyright © 2018, Meson Team',
+ license: 'MIT',
+ sourceFiles: 'test.d',
+ targetType: 'executable',
+ dependencies: urld_dep
+) \ No newline at end of file
diff --git a/test cases/d/11 dub/test.d b/test cases/d/11 dub/test.d
new file mode 100644
index 0000000..7cf7a1d
--- /dev/null
+++ b/test cases/d/11 dub/test.d
@@ -0,0 +1,14 @@
+import std.stdio;
+import url;
+
+void main() {
+ URL url;
+ with (url) {
+ scheme = "soap.beep";
+ host = "beep.example.net";
+ port = 1772;
+ path = "/serverinfo/info";
+ queryParams.add("token", "my-api-token");
+ }
+ writeln(url);
+} \ No newline at end of file
diff --git a/wraptool.py b/wraptool.py
deleted file mode 100755
index a5ee9ef..0000000
--- a/wraptool.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright 2016 The Meson development team
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from mesonbuild.wrap import wraptool
-import sys
-
-if __name__ == '__main__':
- print('Warning: This executable is deprecated. Use "meson wrap" instead.',
- file=sys.stderr)
- sys.exit(wraptool.run(sys.argv[1:]))