aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Rust-module.md35
-rw-r--r--docs/markdown/_Sidebar.md1
-rw-r--r--docs/markdown/snippets/unstable-rust-module.md4
-rw-r--r--docs/sitemap.txt11
-rw-r--r--docs/theme/extra/templates/navbar_links.html45
-rw-r--r--mesonbuild/modules/unstable_rust.py137
-rwxr-xr-xrun_mypy.py1
-rw-r--r--test cases/rust/9 unit tests/meson.build11
-rw-r--r--test cases/rust/9 unit tests/test2.rs11
9 files changed, 229 insertions, 27 deletions
diff --git a/docs/markdown/Rust-module.md b/docs/markdown/Rust-module.md
new file mode 100644
index 0000000..0fdba94
--- /dev/null
+++ b/docs/markdown/Rust-module.md
@@ -0,0 +1,35 @@
+---
+short-description: Rust language integration module
+authors:
+ - name: Dylan Baker
+ email: dylan@pnwbakers.com
+ years: [2020]
+...
+
+# Unstable Rust module
+
+*(new in 0.57.0)*
+
+**Note** Unstable modules make no backwards compatible API guarantees.
+
+The rust module provides helper to integrate rust code into meson. The goal
+is to make using rust in meson more pleasant, while still remaining mesonic,
+this means that it attempts to make rust work more like meson, rather than
+meson work more like rust.
+
+## Functions
+
+### test(name: string, target: library | executable, dependencies: []Dependency)
+
+This function creates a new rust unittest target from an existing rust based
+target, which may be a library or executable. It does this by copying the
+sources and arguments passed to the original target and adding the `--test`
+argument to the compilation, then creates a new test target which calls that
+executable, using the rust test protocol.
+
+This accepts all of the keyword arguments as the
+[`test`](Reference-manual.md#test) function except `protocol`, it will set
+that automatically.
+
+Additional, test only dependencies may be passed via the dependencies
+argument.
diff --git a/docs/markdown/_Sidebar.md b/docs/markdown/_Sidebar.md
index 2637d68..0ca1762 100644
--- a/docs/markdown/_Sidebar.md
+++ b/docs/markdown/_Sidebar.md
@@ -12,3 +12,4 @@
* [gnome](Gnome-module.md)
* [i18n](i18n-module.md)
* [pkgconfig](Pkgconfig-module.md)
+* [rust](Rust-module.md)
diff --git a/docs/markdown/snippets/unstable-rust-module.md b/docs/markdown/snippets/unstable-rust-module.md
new file mode 100644
index 0000000..15a7ecb
--- /dev/null
+++ b/docs/markdown/snippets/unstable-rust-module.md
@@ -0,0 +1,4 @@
+## Untable Rust module
+
+A new unstable module has been added to make using rust with meson easier.
+Currently it adds a single function to ease defining rust tests.
diff --git a/docs/sitemap.txt b/docs/sitemap.txt
index 4cae9fe..3164440 100644
--- a/docs/sitemap.txt
+++ b/docs/sitemap.txt
@@ -34,24 +34,25 @@ index.md
Disabler.md
Modules.md
CMake-module.md
+ Cuda-module.md
Dlang-module.md
+ External-Project-module.md
Fs-module.md
Gnome-module.md
Hotdoc-module.md
- i18n-module.md
Icestorm-module.md
+ Keyval-module.md
Pkgconfig-module.md
- Python-module.md
Python-3-module.md
+ Python-module.md
Qt4-module.md
Qt5-module.md
RPM-module.md
+ Rust-module.md
Simd-module.md
SourceSet-module.md
Windows-module.md
- Cuda-module.md
- Keyval-module.md
- External-Project-module.md
+ i18n-module.md
Java.md
Vala.md
D.md
diff --git a/docs/theme/extra/templates/navbar_links.html b/docs/theme/extra/templates/navbar_links.html
index 832bd2c..8df082f 100644
--- a/docs/theme/extra/templates/navbar_links.html
+++ b/docs/theme/extra/templates/navbar_links.html
@@ -5,28 +5,29 @@
Modules <span class="caret"></span>
</a>
<ul class="dropdown-menu" id="modules-menu">
- @for tup in ( \
- ("CMake-module.html","CMake"), \
- ("Cuda-module.html","CUDA"), \
- ("Dlang-module.html","Dlang"), \
- ("Fs-module.html","Filesystem"), \
- ("Gnome-module.html","GNOME"), \
- ("Hotdoc-module.html","Hotdoc"), \
- ("i18n-module.html","i18n"), \
- ("Icestorm-module.html","Icestorm"), \
- ("Keyval-module.html","Keyval"), \
- ("Pkgconfig-module.html","Pkgconfig"), \
- ("Python-module.html","Python"), \
- ("Python-3-module.html","Python 3"), \
- ("Qt4-module.html","Qt4"), \
- ("Qt5-module.html","Qt5"), \
- ("RPM-module.html","RPM"), \
- ("SourceSet-module.html","SourceSet"), \
- ("Windows-module.html","Windows")):
- <li>
- <a href="@tup[0]">@tup[1]</a>
- </li>
- @end
+ @for tup in [ \
+ ("CMake-module.html","CMake"), \
+ ("Cuda-module.html","CUDA"), \
+ ("Dlang-module.html","Dlang"), \
+ ("Fs-module.html","Filesystem"), \
+ ("Gnome-module.html","GNOME"), \
+ ("Hotdoc-module.html","Hotdoc"), \
+ ("Icestorm-module.html","Icestorm"), \
+ ("Keyval-module.html","Keyval"), \
+ ("Pkgconfig-module.html","Pkgconfig"), \
+ ("Python-3-module.html","Python 3"), \
+ ("Python-module.html","Python"), \
+ ("Qt4-module.html","Qt4"), \
+ ("Qt5-module.html","Qt5"), \
+ ("RPM-module.html","RPM"), \
+ ("Rust-module.html","Rust"), \
+ ("SourceSet-module.html","SourceSet"), \
+ ("Windows-module.html","Windows"), \
+ ("i18n-module.html","i18n")]:
+ <li>
+ <a href="@tup[0]">@tup[1]</a>
+ </li>
+ @end
</ul>
</li>
\
diff --git a/mesonbuild/modules/unstable_rust.py b/mesonbuild/modules/unstable_rust.py
new file mode 100644
index 0000000..72b5217
--- /dev/null
+++ b/mesonbuild/modules/unstable_rust.py
@@ -0,0 +1,137 @@
+# Copyright © 2020 Intel Corporation
+
+# 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 typing as T
+
+from . import ExtensionModule, ModuleReturnValue
+from .. import mlog
+from ..build import BuildTarget, Executable, InvalidArguments
+from ..dependencies import Dependency, ExternalLibrary
+from ..interpreter import ExecutableHolder, permitted_kwargs
+from ..interpreterbase import InterpreterException, permittedKwargs, FeatureNew
+from ..mesonlib import stringlistify, unholder, listify
+
+if T.TYPE_CHECKING:
+ from ..interpreter import ModuleState, Interpreter
+
+
+class RustModule(ExtensionModule):
+
+ """A module that holds helper functions for rust."""
+
+ @FeatureNew('rust module', '0.57.0')
+ def __init__(self, interpreter: 'Interpreter') -> None:
+ super().__init__(interpreter)
+
+ @permittedKwargs(permitted_kwargs['test'] | {'dependencies'} ^ {'protocol'})
+ def test(self, state: 'ModuleState', args: T.List, kwargs: T.Dict[str, T.Any]) -> ModuleReturnValue:
+ """Generate a rust test target from a given rust target.
+
+ Rust puts it's unitests inside it's main source files, unlike most
+ languages that put them in external files. This means that normally
+ you have to define two seperate targets with basically the same
+ arguments to get tests:
+
+ ```meson
+ rust_lib_sources = [...]
+ rust_lib = static_library(
+ 'rust_lib',
+ rust_lib_sources,
+ )
+
+ rust_lib_test = executable(
+ 'rust_lib_test',
+ rust_lib_sources,
+ rust_args : ['--test'],
+ )
+
+ test(
+ 'rust_lib_test',
+ rust_lib_test,
+ protocol : 'rust',
+ )
+ ```
+
+ This is all fine, but not very DRY. This method makes it much easier
+ to define rust tests:
+
+ ```meson
+ rust = import('unstable-rust')
+
+ rust_lib = static_library(
+ 'rust_lib',
+ [sources],
+ )
+
+ rust.test('rust_lib_test', rust_lib)
+ ```
+ """
+ if len(args) != 2:
+ raise InterpreterException('rustmod.test() takes exactly 2 positional arguments')
+ name: str = args[0]
+ if not isinstance(name, str):
+ raise InterpreterException('First positional argument to rustmod.test() must be a string')
+ base_target: BuildTarget = unholder(args[1])
+ if not isinstance(base_target, BuildTarget):
+ raise InterpreterException('Second positional argument to rustmod.test() must be a library or executable')
+ if not base_target.get_using_rustc():
+ raise InterpreterException('Second positional argument to rustmod.test() must be a rust based target')
+ extra_args = stringlistify(kwargs.get('args', []))
+
+ # Delete any arguments we don't want passed
+ if '--test' in extra_args:
+ mlog.warning('Do not add --test to rustmod.test arguments')
+ extra_args.remove('--test')
+ if '--format' in extra_args:
+ mlog.warning('Do not add --format to rustmod.test arguments')
+ i = extra_args.index('--format')
+ # Also delete the argument to --format
+ del extra_args[i + 1]
+ del extra_args[i]
+ for i, a in enumerate(extra_args):
+ if a.startswith('--format='):
+ del extra_args[i]
+ break
+
+ dependencies = unholder(listify(kwargs.get('dependencies', [])))
+ for d in dependencies:
+ if not isinstance(d, (Dependency, ExternalLibrary)):
+ raise InvalidArguments('dependencies must be a dependency or external library')
+
+ kwargs['args'] = extra_args + ['--test', '--format', 'pretty']
+ kwargs['protocol'] = 'rust'
+
+ new_target_kwargs = base_target.kwargs.copy()
+ # Don't mutate the shallow copied list, instead replace it with a new
+ # one
+ new_target_kwargs['rust_args'] = new_target_kwargs.get('rust_args', []) + ['--test']
+ new_target_kwargs['install'] = False
+ new_target_kwargs['dependencies'] = new_target_kwargs.get('dependencies', []) + dependencies
+
+ new_target = Executable(
+ name, base_target.subdir, state.subproject,
+ base_target.for_machine, base_target.sources,
+ base_target.objects, base_target.environment,
+ new_target_kwargs
+ )
+
+ e = ExecutableHolder(new_target, self.interpreter)
+ test = self.interpreter.make_test(
+ self.interpreter.current_node, [name, e], kwargs)
+
+ return ModuleReturnValue([], [e, test])
+
+
+def initialize(*args: T.List, **kwargs: T.Dict) -> RustModule:
+ return RustModule(*args, **kwargs) # type: ignore
diff --git a/run_mypy.py b/run_mypy.py
index 01fa9ff..888403c 100755
--- a/run_mypy.py
+++ b/run_mypy.py
@@ -29,6 +29,7 @@ modules = [
'mesonbuild/mintro.py',
'mesonbuild/mlog.py',
'mesonbuild/modules/fs.py',
+ 'mesonbuild/modules/unstable_rust.py',
'mesonbuild/mparser.py',
'mesonbuild/msetup.py',
'mesonbuild/mtest.py',
diff --git a/test cases/rust/9 unit tests/meson.build b/test cases/rust/9 unit tests/meson.build
index 44fd6b6..b649abb 100644
--- a/test cases/rust/9 unit tests/meson.build
+++ b/test cases/rust/9 unit tests/meson.build
@@ -30,3 +30,14 @@ test(
protocol : 'rust',
suite : ['foo'],
)
+
+exe = executable('rust_exe', ['test2.rs', 'test.rs'])
+
+rust = import('unstable-rust')
+rust.test('rust_test_from_exe', exe, should_fail : true)
+
+lib = static_library('rust_static', ['test.rs'])
+rust.test('rust_test_from_static', lib, args: ['--skip', 'test_add_intentional_fail'])
+
+lib = shared_library('rust_shared', ['test.rs'])
+rust.test('rust_test_from_shared', lib, args: ['--skip', 'test_add_intentional_fail'])
diff --git a/test cases/rust/9 unit tests/test2.rs b/test cases/rust/9 unit tests/test2.rs
new file mode 100644
index 0000000..9623c7c
--- /dev/null
+++ b/test cases/rust/9 unit tests/test2.rs
@@ -0,0 +1,11 @@
+mod test;
+use std::env;
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ let first = args[1].parse::<i32>().expect("Invliad value for first argument.");
+ let second = args[2].parse::<i32>().expect("Invliad value for second argument.");
+
+ let new = test::add(first, second);
+ println!("New value: {}", new);
+}