summaryrefslogtreecommitdiffstats
path: root/test cases/rust
diff options
context:
space:
mode:
Diffstat (limited to 'test cases/rust')
-rw-r--r--test cases/rust/1 basic/clippy.toml1
-rw-r--r--test cases/rust/1 basic/meson.build9
-rw-r--r--test cases/rust/1 basic/prog.rs4
-rw-r--r--test cases/rust/1 basic/subdir/meson.build2
-rw-r--r--test cases/rust/1 basic/subdir/prog.rs3
-rw-r--r--test cases/rust/1 basic/test.json8
-rw-r--r--test cases/rust/10 language stds/2015.rs3
-rw-r--r--test cases/rust/10 language stds/2018.rs9
-rw-r--r--test cases/rust/10 language stds/meson.build18
-rw-r--r--test cases/rust/11 generated main/gen.py20
-rw-r--r--test cases/rust/11 generated main/generated_lib_main.rs5
-rw-r--r--test cases/rust/11 generated main/meson.build21
-rw-r--r--test cases/rust/11 generated main/sub/meson.build13
-rw-r--r--test cases/rust/12 bindgen/dependencies/clib2.c5
-rw-r--r--test cases/rust/12 bindgen/dependencies/external_dep.h8
-rw-r--r--test cases/rust/12 bindgen/dependencies/internal_dep.h6
-rw-r--r--test cases/rust/12 bindgen/dependencies/internal_main.rs16
-rw-r--r--test cases/rust/12 bindgen/dependencies/meson.build43
-rw-r--r--test cases/rust/12 bindgen/include/other.h6
-rw-r--r--test cases/rust/12 bindgen/meson.build83
-rw-r--r--test cases/rust/12 bindgen/src/gen_header.py19
-rw-r--r--test cases/rust/12 bindgen/src/header.h8
-rw-r--r--test cases/rust/12 bindgen/src/main.rs14
-rw-r--r--test cases/rust/12 bindgen/src/main2.rs15
-rw-r--r--test cases/rust/12 bindgen/src/source.c8
-rw-r--r--test cases/rust/12 bindgen/sub/meson.build39
-rw-r--r--test cases/rust/12 bindgen/test.json7
-rw-r--r--test cases/rust/13 external c dependencies/c_accessing_zlib.c10
-rw-r--r--test cases/rust/13 external c dependencies/meson.build23
-rw-r--r--test cases/rust/13 external c dependencies/meson_options.txt2
-rw-r--r--test cases/rust/13 external c dependencies/prog.rs9
-rw-r--r--test cases/rust/13 external c dependencies/test.json18
-rw-r--r--test cases/rust/14 external libm/meson.build24
-rw-r--r--test cases/rust/14 external libm/meson_options.txt2
-rw-r--r--test cases/rust/14 external libm/prog.rs5
-rw-r--r--test cases/rust/14 external libm/rs_math.rs12
-rw-r--r--test cases/rust/14 external libm/test.json10
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.c18
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.h34
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.rs9
-rw-r--r--test cases/rust/15 polyglot sharedlib/addertest.c12
-rw-r--r--test cases/rust/15 polyglot sharedlib/meson.build20
-rw-r--r--test cases/rust/16 internal c dependencies/lib.c6
-rw-r--r--test cases/rust/16 internal c dependencies/lib.h22
-rw-r--r--test cases/rust/16 internal c dependencies/main.rs9
-rw-r--r--test cases/rust/16 internal c dependencies/meson.build14
-rwxr-xr-xtest cases/rust/16 internal c dependencies/test.py25
-rw-r--r--test cases/rust/17 staticlib link staticlib/branch.rs4
-rw-r--r--test cases/rust/17 staticlib link staticlib/leaf.rs1
-rw-r--r--test cases/rust/17 staticlib link staticlib/meson.build8
-rw-r--r--test cases/rust/17 staticlib link staticlib/prog.c7
-rw-r--r--test cases/rust/17 staticlib link staticlib/test.json7
-rw-r--r--test cases/rust/18 proc-macro/meson.build19
-rw-r--r--test cases/rust/18 proc-macro/proc.rs7
-rw-r--r--test cases/rust/18 proc-macro/use.rs8
-rwxr-xr-xtest cases/rust/19 structured sources/gen.py20
-rw-r--r--test cases/rust/19 structured sources/main-gen-copy.rs5
-rw-r--r--test cases/rust/19 structured sources/meson.build58
-rwxr-xr-xtest cases/rust/19 structured sources/no_copy_test.py18
-rw-r--r--test cases/rust/19 structured sources/priv.rs3
-rw-r--r--test cases/rust/19 structured sources/src/foo.rs.in4
-rw-r--r--test cases/rust/19 structured sources/src/main.rs5
-rw-r--r--test cases/rust/19 structured sources/src2/foo/mod.rs4
-rw-r--r--test cases/rust/19 structured sources/src2/main-unique.rs5
-rw-r--r--test cases/rust/19 structured sources/src2/meson.build4
-rw-r--r--test cases/rust/2 sharedlib/meson.build17
-rw-r--r--test cases/rust/2 sharedlib/prog.rs3
-rw-r--r--test cases/rust/2 sharedlib/stuff.rs11
-rw-r--r--test cases/rust/2 sharedlib/test.json10
-rw-r--r--test cases/rust/2 sharedlib/value.c3
-rw-r--r--test cases/rust/3 staticlib/meson.build7
-rw-r--r--test cases/rust/3 staticlib/other.rs5
-rw-r--r--test cases/rust/3 staticlib/prog.rs5
-rw-r--r--test cases/rust/3 staticlib/stuff.rs14
-rw-r--r--test cases/rust/3 staticlib/test.json7
-rw-r--r--test cases/rust/3 staticlib/value.c5
-rw-r--r--test cases/rust/4 polyglot/meson.build9
-rw-r--r--test cases/rust/4 polyglot/prog.c8
-rw-r--r--test cases/rust/4 polyglot/stuff.rs6
-rw-r--r--test cases/rust/4 polyglot/test.json10
-rw-r--r--test cases/rust/5 polyglot static/clib.c12
-rw-r--r--test cases/rust/5 polyglot static/meson.build18
-rw-r--r--test cases/rust/5 polyglot static/prog.c7
-rw-r--r--test cases/rust/5 polyglot static/stuff.rs6
-rw-r--r--test cases/rust/5 polyglot static/test.json7
-rw-r--r--test cases/rust/6 named staticlib/meson.build5
-rw-r--r--test cases/rust/6 named staticlib/prog.rs3
-rw-r--r--test cases/rust/6 named staticlib/stuff.rs1
-rw-r--r--test cases/rust/6 named staticlib/test.json7
-rw-r--r--test cases/rust/7 private crate collision/meson.build5
-rw-r--r--test cases/rust/7 private crate collision/prog.rs3
-rw-r--r--test cases/rust/7 private crate collision/rand.rs4
-rw-r--r--test cases/rust/7 private crate collision/test.json7
-rw-r--r--test cases/rust/8 many files/foo.rs3
-rw-r--r--test cases/rust/8 many files/main.rs5
-rw-r--r--test cases/rust/8 many files/meson.build3
-rw-r--r--test cases/rust/9 unit tests/meson.build43
-rw-r--r--test cases/rust/9 unit tests/test.rs24
-rw-r--r--test cases/rust/9 unit tests/test2.rs11
99 files changed, 1158 insertions, 0 deletions
diff --git a/test cases/rust/1 basic/clippy.toml b/test cases/rust/1 basic/clippy.toml
new file mode 100644
index 0000000..e9ac31b
--- /dev/null
+++ b/test cases/rust/1 basic/clippy.toml
@@ -0,0 +1 @@
+blacklisted-names = ["foo"]
diff --git a/test cases/rust/1 basic/meson.build b/test cases/rust/1 basic/meson.build
new file mode 100644
index 0000000..63ad375
--- /dev/null
+++ b/test cases/rust/1 basic/meson.build
@@ -0,0 +1,9 @@
+project('rustprog', 'rust')
+
+e = executable('rust-program', 'prog.rs',
+ rust_args : ['-C', 'lto'], # Just a test
+ install : true
+)
+test('rusttest', e)
+
+subdir('subdir')
diff --git a/test cases/rust/1 basic/prog.rs b/test cases/rust/1 basic/prog.rs
new file mode 100644
index 0000000..f1b3d30
--- /dev/null
+++ b/test cases/rust/1 basic/prog.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let foo = "rust compiler is working";
+ println!("{}", foo);
+}
diff --git a/test cases/rust/1 basic/subdir/meson.build b/test cases/rust/1 basic/subdir/meson.build
new file mode 100644
index 0000000..36a3d4a
--- /dev/null
+++ b/test cases/rust/1 basic/subdir/meson.build
@@ -0,0 +1,2 @@
+e = executable('rust-program2', 'prog.rs', install : true)
+test('rusttest2', e)
diff --git a/test cases/rust/1 basic/subdir/prog.rs b/test cases/rust/1 basic/subdir/prog.rs
new file mode 100644
index 0000000..b171a80
--- /dev/null
+++ b/test cases/rust/1 basic/subdir/prog.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("rust compiler is working");
+}
diff --git a/test cases/rust/1 basic/test.json b/test cases/rust/1 basic/test.json
new file mode 100644
index 0000000..95e6ced
--- /dev/null
+++ b/test cases/rust/1 basic/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/rust-program"},
+ {"type": "pdb", "file": "usr/bin/rust-program"},
+ {"type": "exe", "file": "usr/bin/rust-program2"},
+ {"type": "pdb", "file": "usr/bin/rust-program2"}
+ ]
+}
diff --git a/test cases/rust/10 language stds/2015.rs b/test cases/rust/10 language stds/2015.rs
new file mode 100644
index 0000000..4d28c57
--- /dev/null
+++ b/test cases/rust/10 language stds/2015.rs
@@ -0,0 +1,3 @@
+trait Foo {
+ fn foo(&self, Box<dyn Foo>);
+}
diff --git a/test cases/rust/10 language stds/2018.rs b/test cases/rust/10 language stds/2018.rs
new file mode 100644
index 0000000..4009154
--- /dev/null
+++ b/test cases/rust/10 language stds/2018.rs
@@ -0,0 +1,9 @@
+const fn foo(x: i32) -> i32 {
+ return x + 1;
+}
+
+const VALUE: i32 = foo(-1);
+
+pub fn main() {
+ std::process::exit(VALUE);
+}
diff --git a/test cases/rust/10 language stds/meson.build b/test cases/rust/10 language stds/meson.build
new file mode 100644
index 0000000..9944339
--- /dev/null
+++ b/test cases/rust/10 language stds/meson.build
@@ -0,0 +1,18 @@
+project('rust std options', 'rust')
+
+# this only works in 2018
+new = executable(
+ 'new',
+ '2018.rs',
+ override_options : ['rust_std=2018'],
+)
+
+# this only works in 2015
+old = static_library(
+ 'old',
+ '2015.rs',
+ override_options : ['rust_std=2015'],
+)
+
+
+test('2018 std', new)
diff --git a/test cases/rust/11 generated main/gen.py b/test cases/rust/11 generated main/gen.py
new file mode 100644
index 0000000..c8cfe76
--- /dev/null
+++ b/test cases/rust/11 generated main/gen.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import argparse
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('out')
+ parser.add_argument('--mode', choices=['main', 'lib'], default='main')
+ args = parser.parse_args()
+
+ with open(args.out, 'w') as f:
+ if args.mode == 'main':
+ f.write('fn main() { println!("I prefer tarnish, actually.") }')
+ elif args.mode == 'lib':
+ f.write('pub fn libfun() { println!("I prefer tarnish, actually.") }')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/11 generated main/generated_lib_main.rs b/test cases/rust/11 generated main/generated_lib_main.rs
new file mode 100644
index 0000000..d9b373e
--- /dev/null
+++ b/test cases/rust/11 generated main/generated_lib_main.rs
@@ -0,0 +1,5 @@
+extern crate static_lib_generated as lib;
+
+fn main() {
+ lib::libfun();
+}
diff --git a/test cases/rust/11 generated main/meson.build b/test cases/rust/11 generated main/meson.build
new file mode 100644
index 0000000..695124c
--- /dev/null
+++ b/test cases/rust/11 generated main/meson.build
@@ -0,0 +1,21 @@
+project('generated rust main', 'rust')
+
+gen = find_program('gen.py')
+
+c = custom_target(
+ 'custom_target',
+ command : [gen, '@OUTPUT@'],
+ output : ['main.rs'],
+)
+
+executable('custom_target_main', c)
+executable('custom_target_index_main', c[0])
+
+gener = generator(gen, arguments : ['@OUTPUT@'], output : '@BASENAME@.rs')
+# Doesn't actually use gen.py as input, just a limitation of generators
+executable('generator_main', gener.process(['gen.py']))
+
+subdir('sub')
+executable('custom_target_subdir_main', s)
+
+executable('link_with_generated_lib', 'generated_lib_main.rs', link_with : lib)
diff --git a/test cases/rust/11 generated main/sub/meson.build b/test cases/rust/11 generated main/sub/meson.build
new file mode 100644
index 0000000..3ce96e5
--- /dev/null
+++ b/test cases/rust/11 generated main/sub/meson.build
@@ -0,0 +1,13 @@
+s = custom_target(
+ 'subdir_target',
+ command : [gen, '@OUTPUT@'],
+ output : ['main.rs'],
+)
+
+l = custom_target(
+ 'lib_target',
+ command : [gen, '@OUTPUT@', '--mode', 'lib'],
+ output : ['lib.rs'],
+)
+
+lib = static_library('static_lib_generated', l)
diff --git a/test cases/rust/12 bindgen/dependencies/clib2.c b/test cases/rust/12 bindgen/dependencies/clib2.c
new file mode 100644
index 0000000..63d3e0a
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/clib2.c
@@ -0,0 +1,5 @@
+#include "internal_dep.h"
+
+int64_t add64(const int64_t first, const int64_t second) {
+ return first + second;
+}
diff --git a/test cases/rust/12 bindgen/dependencies/external_dep.h b/test cases/rust/12 bindgen/dependencies/external_dep.h
new file mode 100644
index 0000000..284661b
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/external_dep.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifer: Apache-2.0 */
+/* Copyright © 2022 Intel Corporation */
+
+#include <zlib.h>
+
+struct External {
+ z_stream * stream;
+};
diff --git a/test cases/rust/12 bindgen/dependencies/internal_dep.h b/test cases/rust/12 bindgen/dependencies/internal_dep.h
new file mode 100644
index 0000000..b0629de
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/internal_dep.h
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright © 2022 Intel Corporation
+
+#include "gen.h"
+
+int64_t add64(const int64_t, const int64_t);
diff --git a/test cases/rust/12 bindgen/dependencies/internal_main.rs b/test cases/rust/12 bindgen/dependencies/internal_main.rs
new file mode 100644
index 0000000..4890b43
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/internal_main.rs
@@ -0,0 +1,16 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("internal_dep.rs");
+
+use std::convert::TryInto;
+
+fn main() {
+ unsafe {
+ std::process::exit(add64(0, 0).try_into().unwrap_or(5));
+ };
+}
diff --git a/test cases/rust/12 bindgen/dependencies/meson.build b/test cases/rust/12 bindgen/dependencies/meson.build
new file mode 100644
index 0000000..37e5a42
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/meson.build
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright © 2022 Intel Corporation
+
+dep_zlib = dependency('zlib', required : false, disabler : true)
+
+external_dep_rs = rust.bindgen(
+ input : 'external_dep.h',
+ output : 'external_dep.rs',
+ dependencies : dep_zlib
+)
+
+external_dep = static_library(
+ 'external_dep',
+ [external_dep_rs],
+ dependencies : dep_zlib.partial_dependency(links : true),
+)
+
+rust.test('external dep', external_dep)
+
+int_dep = declare_dependency(
+ sources : [gen_h, gen2_h],
+ include_directories : include_directories('..'),
+)
+
+internal_dep_rs = rust.bindgen(
+ input : 'internal_dep.h',
+ output : 'internal_dep.rs',
+ dependencies : int_dep,
+)
+
+c_lib2 = static_library(
+ 'clib2',
+ 'clib2.c',
+ dependencies : int_dep,
+)
+
+rust_bin_int_dep = executable(
+ 'rust_bin_int_dep',
+ structured_sources(['internal_main.rs', internal_dep_rs]),
+ link_with : [c_lib, c_lib2],
+)
+
+test('generated header dependency', rust_bin_int_dep)
diff --git a/test cases/rust/12 bindgen/include/other.h b/test cases/rust/12 bindgen/include/other.h
new file mode 100644
index 0000000..3f715f1
--- /dev/null
+++ b/test cases/rust/12 bindgen/include/other.h
@@ -0,0 +1,6 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+# pragma once
+
+#include <stdint.h>
diff --git a/test cases/rust/12 bindgen/meson.build b/test cases/rust/12 bindgen/meson.build
new file mode 100644
index 0000000..c05cc06
--- /dev/null
+++ b/test cases/rust/12 bindgen/meson.build
@@ -0,0 +1,83 @@
+# SPDX-license-identifer: Apache-2.0
+# Copyright © 2021-2022 Intel Corporation
+
+project('rustmod bindgen', ['c', 'rust'], meson_version : '>= 0.63')
+
+prog_bindgen = find_program('bindgen', required : false)
+if not prog_bindgen.found()
+ error('MESON_SKIP_TEST bindgen not found')
+endif
+
+# This seems to happen on windows when libclang.dll is not in path or is not
+# valid. We must try to process a header file for this to work.
+#
+# See https://github.com/rust-lang/rust-bindgen/issues/1797
+result = run_command(prog_bindgen, 'include/other.h', check: false)
+if result.returncode() != 0
+ error('MESON_SKIP_TEST bindgen does not seem to work')
+endif
+
+# This is to test the include_directories argument to bindgen
+inc = include_directories('include')
+
+c_lib = static_library('clib', 'src/source.c', include_directories : inc)
+
+rust = import('unstable-rust')
+
+gen = rust.bindgen(
+ input : 'src/header.h',
+ output : 'header.rs',
+ include_directories : 'include',
+)
+
+# see: https://github.com/mesonbuild/meson/issues/8160
+f = configure_file(
+ input : 'src/main.rs',
+ output : 'main.rs',
+ copy : true,
+)
+
+rust_bin = executable(
+ 'rust_bin',
+ [f, gen],
+ link_with : c_lib,
+)
+
+test('main', rust_bin)
+
+# Test a generated header
+gen_h = custom_target(
+ 'gen.h',
+ command : [find_program('src/gen_header.py'), '@INPUT@', '@OUTPUT@'],
+ output : 'gen.h',
+ input : 'src/header.h'
+)
+
+gen2_h = custom_target(
+ 'other.h',
+ command : [find_program('src/gen_header.py'), '@INPUT@', '@OUTPUT@'],
+ output : 'other.h',
+ input : 'include/other.h'
+)
+
+gen_rs = rust.bindgen(
+ input : [gen_h, gen2_h],
+ output : 'gen.rs',
+)
+
+f = configure_file(
+ input : 'src/main2.rs',
+ output : 'main2.rs',
+ copy : true,
+)
+
+rust_bin2 = executable(
+ 'rust_bin2',
+ [f, gen_rs],
+ link_with : c_lib,
+)
+
+test('generated header', rust_bin2)
+
+subdir('sub')
+subdir('dependencies')
diff --git a/test cases/rust/12 bindgen/src/gen_header.py b/test cases/rust/12 bindgen/src/gen_header.py
new file mode 100644
index 0000000..099e4ec
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/gen_header.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+# SPDX-license-identifer: Apache-2.0
+# Copyright © 2021 Intel Corporation
+
+import argparse
+import shutil
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('input')
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ shutil.copy2(args.input, args.output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/12 bindgen/src/header.h b/test cases/rust/12 bindgen/src/header.h
new file mode 100644
index 0000000..2c03f33
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/header.h
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#pragma once
+
+#include "other.h"
+
+int32_t add(const int32_t, const int32_t);
diff --git a/test cases/rust/12 bindgen/src/main.rs b/test cases/rust/12 bindgen/src/main.rs
new file mode 100644
index 0000000..3f85e96
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/main.rs
@@ -0,0 +1,14 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("header.rs");
+
+fn main() {
+ unsafe {
+ std::process::exit(add(0, 0));
+ };
+}
diff --git a/test cases/rust/12 bindgen/src/main2.rs b/test cases/rust/12 bindgen/src/main2.rs
new file mode 100644
index 0000000..a3c28d7
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/main2.rs
@@ -0,0 +1,15 @@
+
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("gen.rs");
+
+fn main() {
+ unsafe {
+ std::process::exit(add(0, 0));
+ };
+}
diff --git a/test cases/rust/12 bindgen/src/source.c b/test cases/rust/12 bindgen/src/source.c
new file mode 100644
index 0000000..d652d28
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/source.c
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#include "header.h"
+
+int32_t add(const int32_t first, const int32_t second) {
+ return first + second;
+}
diff --git a/test cases/rust/12 bindgen/sub/meson.build b/test cases/rust/12 bindgen/sub/meson.build
new file mode 100644
index 0000000..1da360e
--- /dev/null
+++ b/test cases/rust/12 bindgen/sub/meson.build
@@ -0,0 +1,39 @@
+gen_rs3 = rust.bindgen(
+ input : [gen_h, gen2_h],
+ output : 'gen.rs',
+)
+
+f3 = configure_file(
+ input : '../src/main2.rs',
+ output : 'main3.rs',
+ copy : true,
+)
+
+rust_bin3 = executable(
+ 'rust_bin3',
+ [f3, gen_rs3],
+ link_with : c_lib,
+)
+
+test('generated header (subdir)', rust_bin3)
+
+gen4 = rust.bindgen(
+ input : '../src/header.h',
+ output : 'header.rs',
+ include_directories : inc,
+)
+
+# see: https://github.com/mesonbuild/meson/issues/8160
+f4 = configure_file(
+ input : '../src/main.rs',
+ output : 'main.rs',
+ copy : true,
+)
+
+rust_bin4 = executable(
+ 'rust_bin_subdir',
+ [f4, gen4],
+ link_with : c_lib,
+)
+
+test('static header (subdir)', rust_bin4)
diff --git a/test cases/rust/12 bindgen/test.json b/test cases/rust/12 bindgen/test.json
new file mode 100644
index 0000000..11cefc3
--- /dev/null
+++ b/test cases/rust/12 bindgen/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/rust/12 bindgen/meson.build:30: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': include_directories kwarg of type string. Use include_directories('include') instead"
+ }
+ ]
+}
diff --git a/test cases/rust/13 external c dependencies/c_accessing_zlib.c b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
new file mode 100644
index 0000000..358b989
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <zlib.h>
+
+void c_accessing_zlib(void) {
+ struct z_stream_s zstream;
+ printf("Hello from C!\n");
+ memset(&zstream, 0, sizeof(zstream));
+ inflateInit(&zstream);
+}
diff --git a/test cases/rust/13 external c dependencies/meson.build b/test cases/rust/13 external c dependencies/meson.build
new file mode 100644
index 0000000..c91674c
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson.build
@@ -0,0 +1,23 @@
+project('rust linking to c using dependency', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+dep_zlib = dependency('zlib', static : get_option('static'), method : get_option('method'), required : false)
+if not dep_zlib.found()
+ error('MESON_SKIP_TEST: Could not find a @0@ zlib'.format(get_option('static') ? 'static' : 'shared'))
+endif
+
+l = static_library(
+ 'c_accessing_zlib',
+ 'c_accessing_zlib.c',
+ dependencies: [dep_zlib],
+)
+
+e = executable(
+ 'prog', 'prog.rs',
+ link_with : l,
+)
+
+test('cdepstest', e)
diff --git a/test cases/rust/13 external c dependencies/meson_options.txt b/test cases/rust/13 external c dependencies/meson_options.txt
new file mode 100644
index 0000000..f501348
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson_options.txt
@@ -0,0 +1,2 @@
+option('static', type : 'boolean')
+option('method', type : 'string')
diff --git a/test cases/rust/13 external c dependencies/prog.rs b/test cases/rust/13 external c dependencies/prog.rs
new file mode 100644
index 0000000..b30ec24
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/prog.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn c_accessing_zlib();
+}
+
+fn main() {
+ unsafe {
+ c_accessing_zlib();
+ }
+}
diff --git a/test cases/rust/13 external c dependencies/test.json b/test cases/rust/13 external c dependencies/test.json
new file mode 100644
index 0000000..423581f
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/test.json
@@ -0,0 +1,18 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": true },
+ { "val": false }
+ ],
+ "method": [
+ { "val": "pkg-config" },
+ { "val": "cmake" },
+ { "val": "system" }
+ ]
+ },
+ "exclude": [
+ { "static": true, "method": "pkg-config" }
+ ]
+ }
+}
diff --git a/test cases/rust/14 external libm/meson.build b/test cases/rust/14 external libm/meson.build
new file mode 100644
index 0000000..e42eefe
--- /dev/null
+++ b/test cases/rust/14 external libm/meson.build
@@ -0,0 +1,24 @@
+project('rust linking to libm', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+cc = meson.get_compiler('c')
+dep_m = cc.find_library('m', required : false, static : get_option('static'))
+if not dep_m.found()
+ error('MESON_SKIP_TEST: Could not find a @0@ libm'.format(get_option('static') ? 'static' : 'shared'))
+endif
+
+librs_math = static_library(
+ 'rs_math',
+ 'rs_math.rs',
+ dependencies : [dep_m],
+)
+
+e = executable(
+ 'prog', 'prog.rs',
+ link_with : [librs_math],
+)
+
+test('cdepstest', e)
diff --git a/test cases/rust/14 external libm/meson_options.txt b/test cases/rust/14 external libm/meson_options.txt
new file mode 100644
index 0000000..f501348
--- /dev/null
+++ b/test cases/rust/14 external libm/meson_options.txt
@@ -0,0 +1,2 @@
+option('static', type : 'boolean')
+option('method', type : 'string')
diff --git a/test cases/rust/14 external libm/prog.rs b/test cases/rust/14 external libm/prog.rs
new file mode 100644
index 0000000..6745977
--- /dev/null
+++ b/test cases/rust/14 external libm/prog.rs
@@ -0,0 +1,5 @@
+extern crate rs_math;
+
+fn main() {
+ assert_eq!(rs_math::rs_log2(8.0), 3.0);
+}
diff --git a/test cases/rust/14 external libm/rs_math.rs b/test cases/rust/14 external libm/rs_math.rs
new file mode 100644
index 0000000..ef53a5c
--- /dev/null
+++ b/test cases/rust/14 external libm/rs_math.rs
@@ -0,0 +1,12 @@
+#![crate_name = "rs_math"]
+
+use std::os::raw::c_double;
+
+extern "C" {
+ fn log2(n: c_double) -> c_double;
+}
+
+#[no_mangle]
+pub extern fn rs_log2(n: c_double) -> c_double {
+ unsafe { log2(n) }
+}
diff --git a/test cases/rust/14 external libm/test.json b/test cases/rust/14 external libm/test.json
new file mode 100644
index 0000000..42d8fe9
--- /dev/null
+++ b/test cases/rust/14 external libm/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": true },
+ { "val": false }
+ ]
+ }
+ }
+}
diff --git a/test cases/rust/15 polyglot sharedlib/adder.c b/test cases/rust/15 polyglot sharedlib/adder.c
new file mode 100644
index 0000000..66613ed
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.c
@@ -0,0 +1,18 @@
+#include<adder.h>
+#include<stdlib.h>
+
+struct _Adder {
+ int number;
+};
+
+adder* adder_create(int number) {
+ adder *a = malloc(sizeof(struct _Adder));
+ a->number = number;
+ return a;
+}
+
+// adder_add is implemented in the Rust file.
+
+void adder_destroy(adder *a) {
+ free(a);
+}
diff --git a/test cases/rust/15 polyglot sharedlib/adder.h b/test cases/rust/15 polyglot sharedlib/adder.h
new file mode 100644
index 0000000..fb2105e
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #define DLL_PUBLIC
+ #endif
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+typedef struct _Adder adder;
+
+DLL_PUBLIC extern adder* adder_create(int number);
+DLL_PUBLIC extern int adder_add(adder *a, int number);
+DLL_PUBLIC extern void adder_destroy(adder*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/rust/15 polyglot sharedlib/adder.rs b/test cases/rust/15 polyglot sharedlib/adder.rs
new file mode 100644
index 0000000..9095350
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.rs
@@ -0,0 +1,9 @@
+#[repr(C)]
+pub struct Adder {
+ pub number: i32
+}
+
+#[no_mangle]
+pub extern fn adder_add(a: &Adder, number: i32) -> i32 {
+ return a.number + number;
+}
diff --git a/test cases/rust/15 polyglot sharedlib/addertest.c b/test cases/rust/15 polyglot sharedlib/addertest.c
new file mode 100644
index 0000000..87e45b6
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/addertest.c
@@ -0,0 +1,12 @@
+#include<stdlib.h>
+#include<adder.h>
+
+int main(int argc, char **argv) {
+ adder *a = adder_create(3);
+ int result = adder_add(a, 4);
+ if(result != 7) {
+ return 1;
+ }
+ adder_destroy(a);
+ return 0;
+}
diff --git a/test cases/rust/15 polyglot sharedlib/meson.build b/test cases/rust/15 polyglot sharedlib/meson.build
new file mode 100644
index 0000000..13fc8fd
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/meson.build
@@ -0,0 +1,20 @@
+project('adder', 'c', 'rust', version: '1.0.0')
+
+if build_machine.system() != 'linux'
+ error('MESON_SKIP_TEST, this test only works on Linux. Patches welcome.')
+endif
+
+thread_dep = dependency('threads')
+dl_dep = meson.get_compiler('c').find_library('dl', required: false)
+m_dep = meson.get_compiler('c').find_library('m', required: false)
+
+rl = static_library('radder', 'adder.rs', rust_crate_type: 'staticlib')
+
+l = shared_library('adder', 'adder.c',
+ c_args: '-DBUILDING_ADDER',
+ link_with: rl,
+ version: '1.0.0',
+ soversion: '1',
+ link_args: '-Wl,-u,adder_add', # Ensure that Rust code is not removed as unused.
+ dependencies: [thread_dep, dl_dep, m_dep])
+test('adder', executable('addertest', 'addertest.c', link_with: l))
diff --git a/test cases/rust/16 internal c dependencies/lib.c b/test cases/rust/16 internal c dependencies/lib.c
new file mode 100644
index 0000000..e852de6
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/lib.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+#include "lib.h"
+
+void c_func(void) {
+ printf("This is a " MODE " C library\n");
+}
diff --git a/test cases/rust/16 internal c dependencies/lib.h b/test cases/rust/16 internal c dependencies/lib.h
new file mode 100644
index 0000000..847bd16
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/lib.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #define DLL_PUBLIC
+ #endif
+ #else
+ #pragma message("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+DLL_PUBLIC void c_func(void);
diff --git a/test cases/rust/16 internal c dependencies/main.rs b/test cases/rust/16 internal c dependencies/main.rs
new file mode 100644
index 0000000..5383599
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/main.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn c_func();
+}
+
+fn main() {
+ unsafe {
+ c_func();
+ }
+}
diff --git a/test cases/rust/16 internal c dependencies/meson.build b/test cases/rust/16 internal c dependencies/meson.build
new file mode 100644
index 0000000..c7476d7
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/meson.build
@@ -0,0 +1,14 @@
+project('internal dependencies', 'c', 'rust')
+
+test_prog = find_program('test.py')
+
+static = static_library('static', 'lib.c', c_args : '-DMODE="static"')
+exe = executable('static', 'main.rs', link_with : static)
+test('static linkage', test_prog, args : [exe, 'This is a static C library'])
+
+# Shared linkage with rust doesn't work on macOS with meson, yet
+if host_machine.system() != 'darwin'
+ shared = shared_library('shared', 'lib.c', c_args : '-DMODE="shared"')
+ exe = executable('shared', 'main.rs', link_with : shared)
+ test('shared linkage', test_prog, args : [exe, 'This is a shared C library'])
+endif
diff --git a/test cases/rust/16 internal c dependencies/test.py b/test cases/rust/16 internal c dependencies/test.py
new file mode 100755
index 0000000..dacec12
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/test.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+import argparse
+import subprocess
+import sys
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('command')
+ parser.add_argument('expected')
+ args = parser.parse_args()
+
+ out = subprocess.run(args.command, stdout=subprocess.PIPE)
+ actual = out.stdout.decode().strip()
+
+ if args.expected != actual:
+ print('expected:', args.expected, file=sys.stderr)
+ print('actual: ', actual, file=sys.stderr)
+ sys.exit(1)
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/17 staticlib link staticlib/branch.rs b/test cases/rust/17 staticlib link staticlib/branch.rs
new file mode 100644
index 0000000..29e1cd0
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/branch.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub extern "C" fn what_have_we_here() -> i32 {
+ leaf::HOW_MANY * leaf::HOW_MANY
+}
diff --git a/test cases/rust/17 staticlib link staticlib/leaf.rs b/test cases/rust/17 staticlib link staticlib/leaf.rs
new file mode 100644
index 0000000..2c697f7
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/leaf.rs
@@ -0,0 +1 @@
+pub const HOW_MANY: i32 = 5;
diff --git a/test cases/rust/17 staticlib link staticlib/meson.build b/test cases/rust/17 staticlib link staticlib/meson.build
new file mode 100644
index 0000000..68d08f3
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/meson.build
@@ -0,0 +1,8 @@
+project('staticlib link staticlib', 'c', 'rust')
+
+leaf = static_library('leaf', 'leaf.rs', rust_crate_type : 'rlib')
+# Even though leaf is linked using link_with, this gets implicitly promoted to link_whole because
+# it is an internal Rust project.
+branch = static_library('branch', 'branch.rs', link_with: leaf, rust_crate_type : 'staticlib', install : true)
+e = executable('prog', 'prog.c', link_with : branch, install : true)
+test('linktest', e)
diff --git a/test cases/rust/17 staticlib link staticlib/prog.c b/test cases/rust/17 staticlib link staticlib/prog.c
new file mode 100644
index 0000000..853391e
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/prog.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int what_have_we_here();
+
+int main(void) {
+ printf("printing %d\n", what_have_we_here());
+}
diff --git a/test cases/rust/17 staticlib link staticlib/test.json b/test cases/rust/17 staticlib link staticlib/test.json
new file mode 100644
index 0000000..c08ffea
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libbranch.a"}
+ ]
+}
diff --git a/test cases/rust/18 proc-macro/meson.build b/test cases/rust/18 proc-macro/meson.build
new file mode 100644
index 0000000..01c4cbe
--- /dev/null
+++ b/test cases/rust/18 proc-macro/meson.build
@@ -0,0 +1,19 @@
+project('rust proc-macro', 'rust')
+
+if build_machine.system() != 'linux'
+ error('MESON_SKIP_TEST, this test only works on Linux. Patches welcome.')
+endif
+
+pm = shared_library(
+ 'proc_macro_examples',
+ 'proc.rs',
+ rust_crate_type : 'proc-macro',
+)
+
+main = executable(
+ 'main',
+ 'use.rs',
+ link_with : pm
+)
+
+test('main_test', main)
diff --git a/test cases/rust/18 proc-macro/proc.rs b/test cases/rust/18 proc-macro/proc.rs
new file mode 100644
index 0000000..53935e4
--- /dev/null
+++ b/test cases/rust/18 proc-macro/proc.rs
@@ -0,0 +1,7 @@
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn make_answer(_item: TokenStream) -> TokenStream {
+ "fn answer() -> u32 { 42 }".parse().unwrap()
+}
diff --git a/test cases/rust/18 proc-macro/use.rs b/test cases/rust/18 proc-macro/use.rs
new file mode 100644
index 0000000..0b6342b
--- /dev/null
+++ b/test cases/rust/18 proc-macro/use.rs
@@ -0,0 +1,8 @@
+extern crate proc_macro_examples;
+use proc_macro_examples::make_answer;
+
+make_answer!();
+
+fn main() {
+ assert_eq!(42, answer());
+}
diff --git a/test cases/rust/19 structured sources/gen.py b/test cases/rust/19 structured sources/gen.py
new file mode 100755
index 0000000..16e5c04
--- /dev/null
+++ b/test cases/rust/19 structured sources/gen.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import argparse
+import textwrap
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ with open(args.output, 'w') as f:
+ f.write(textwrap.dedent('''\
+ pub fn bar() -> () {
+ println!("Hello, World!");
+ }'''))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/19 structured sources/main-gen-copy.rs b/test cases/rust/19 structured sources/main-gen-copy.rs
new file mode 100644
index 0000000..db66a51
--- /dev/null
+++ b/test cases/rust/19 structured sources/main-gen-copy.rs
@@ -0,0 +1,5 @@
+include!(r#"@dir@/include.rs"#);
+
+pub fn main() {
+ priv_func();
+}
diff --git a/test cases/rust/19 structured sources/meson.build b/test cases/rust/19 structured sources/meson.build
new file mode 100644
index 0000000..d84e83f
--- /dev/null
+++ b/test cases/rust/19 structured sources/meson.build
@@ -0,0 +1,58 @@
+project('structured input', 'rust')
+
+foo_mod_rs = configure_file(
+ input : 'src/foo.rs.in',
+ output : 'mod.rs',
+ configuration : {'message' : 'Hello, World!'},
+)
+
+conf_file = executable(
+ 'main_conf_file',
+ structured_sources(
+ 'src/main.rs',
+ {'foo' : [foo_mod_rs]},
+ ),
+)
+
+ct = custom_target(
+ 'foo.rs',
+ output : 'foo.rs',
+ command : ['gen.py', '@OUTPUT@'],
+)
+
+target = executable(
+ 'main_custom_target',
+ structured_sources(
+ ['src/main.rs', ct],
+ ),
+)
+
+# Should not be coppied
+executable(
+ 'no_copy_target',
+ structured_sources(
+ ['src2/main-unique.rs'],
+ {'foo': 'src2/foo/mod.rs'},
+ ),
+)
+
+test('no-copy', find_program('no_copy_test.py'), args : meson.current_build_dir())
+
+subdir('src2')
+
+executable('copy-no-gen', srcs2)
+
+m_src = configure_file(
+ input : 'main-gen-copy.rs',
+ output : 'main-gen-copy.rs',
+ configuration : {'dir' : meson.current_build_dir().replace('\\', '/')},
+)
+
+m_src2 = configure_file(
+ input : 'priv.rs',
+ output : 'include.rs',
+ copy : true
+)
+
+executable('gen-no-copy', structured_sources([m_src, m_src2]))
+
diff --git a/test cases/rust/19 structured sources/no_copy_test.py b/test cases/rust/19 structured sources/no_copy_test.py
new file mode 100755
index 0000000..91506b2
--- /dev/null
+++ b/test cases/rust/19 structured sources/no_copy_test.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('builddir')
+ args = parser.parse_args()
+
+ for _, _, files in os.walk(args.builddir):
+ if 'main-unique.rs' in files:
+ exit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/19 structured sources/priv.rs b/test cases/rust/19 structured sources/priv.rs
new file mode 100644
index 0000000..aad196b
--- /dev/null
+++ b/test cases/rust/19 structured sources/priv.rs
@@ -0,0 +1,3 @@
+fn priv_func() {
+ std::process::exit(0);
+}
diff --git a/test cases/rust/19 structured sources/src/foo.rs.in b/test cases/rust/19 structured sources/src/foo.rs.in
new file mode 100644
index 0000000..4f3fc42
--- /dev/null
+++ b/test cases/rust/19 structured sources/src/foo.rs.in
@@ -0,0 +1,4 @@
+
+pub fn bar() -> () {
+ println!("@message@");
+}
diff --git a/test cases/rust/19 structured sources/src/main.rs b/test cases/rust/19 structured sources/src/main.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src/main.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/19 structured sources/src2/foo/mod.rs b/test cases/rust/19 structured sources/src2/foo/mod.rs
new file mode 100644
index 0000000..9463d95
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/foo/mod.rs
@@ -0,0 +1,4 @@
+
+pub fn bar() -> () {
+ println!("Hello, World!");
+}
diff --git a/test cases/rust/19 structured sources/src2/main-unique.rs b/test cases/rust/19 structured sources/src2/main-unique.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/main-unique.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/19 structured sources/src2/meson.build b/test cases/rust/19 structured sources/src2/meson.build
new file mode 100644
index 0000000..b4844d2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/meson.build
@@ -0,0 +1,4 @@
+srcs2 = structured_sources(
+ ['main-unique.rs'],
+ {'foo': 'foo/mod.rs'},
+)
diff --git a/test cases/rust/2 sharedlib/meson.build b/test cases/rust/2 sharedlib/meson.build
new file mode 100644
index 0000000..295fa04
--- /dev/null
+++ b/test cases/rust/2 sharedlib/meson.build
@@ -0,0 +1,17 @@
+project('rust shared library', 'rust', 'c')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+s = static_library('static', 'value.c')
+l = shared_library('stuff', 'stuff.rs', link_whole : s, install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+
+if build_machine.system() == 'windows'
+ rustup = find_program('rustup')
+ test('linktest', rustup,
+ args: ['run', 'stable', e])
+else
+ test('linktest', e)
+endif
diff --git a/test cases/rust/2 sharedlib/prog.rs b/test cases/rust/2 sharedlib/prog.rs
new file mode 100644
index 0000000..fbf3181
--- /dev/null
+++ b/test cases/rust/2 sharedlib/prog.rs
@@ -0,0 +1,3 @@
+extern crate stuff;
+
+fn main() { println!("printing: {}", stuff::explore()); }
diff --git a/test cases/rust/2 sharedlib/stuff.rs b/test cases/rust/2 sharedlib/stuff.rs
new file mode 100644
index 0000000..e7c0521
--- /dev/null
+++ b/test cases/rust/2 sharedlib/stuff.rs
@@ -0,0 +1,11 @@
+#![crate_name = "stuff"]
+
+extern "C" {
+ fn c_value() -> i32;
+}
+
+pub fn explore() -> String {
+ unsafe {
+ format!("library{}string", c_value())
+ }
+}
diff --git a/test cases/rust/2 sharedlib/test.json b/test cases/rust/2 sharedlib/test.json
new file mode 100644
index 0000000..585fdeb
--- /dev/null
+++ b/test cases/rust/2 sharedlib/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "pdb", "file": "usr/bin/stuff"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"}
+ ]
+}
diff --git a/test cases/rust/2 sharedlib/value.c b/test cases/rust/2 sharedlib/value.c
new file mode 100644
index 0000000..d17b6de
--- /dev/null
+++ b/test cases/rust/2 sharedlib/value.c
@@ -0,0 +1,3 @@
+int c_value(void) {
+ return 7;
+}
diff --git a/test cases/rust/3 staticlib/meson.build b/test cases/rust/3 staticlib/meson.build
new file mode 100644
index 0000000..cf8e103
--- /dev/null
+++ b/test cases/rust/3 staticlib/meson.build
@@ -0,0 +1,7 @@
+project('rust static library', 'rust', 'c')
+
+o = static_library('other', 'other.rs')
+v = static_library('value', 'value.c')
+l = static_library('stuff', 'stuff.rs', link_whole : [o, v], install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/3 staticlib/other.rs b/test cases/rust/3 staticlib/other.rs
new file mode 100644
index 0000000..037be33
--- /dev/null
+++ b/test cases/rust/3 staticlib/other.rs
@@ -0,0 +1,5 @@
+pub fn explore(
+ value: i32,
+) -> String {
+ format!("library{}string", value)
+}
diff --git a/test cases/rust/3 staticlib/prog.rs b/test cases/rust/3 staticlib/prog.rs
new file mode 100644
index 0000000..eee2653
--- /dev/null
+++ b/test cases/rust/3 staticlib/prog.rs
@@ -0,0 +1,5 @@
+extern crate stuff;
+
+fn main() {
+ println!("printing: {}", stuff::explore());
+}
diff --git a/test cases/rust/3 staticlib/stuff.rs b/test cases/rust/3 staticlib/stuff.rs
new file mode 100644
index 0000000..7cfcdff
--- /dev/null
+++ b/test cases/rust/3 staticlib/stuff.rs
@@ -0,0 +1,14 @@
+#![crate_name = "stuff"]
+
+extern crate other;
+
+extern "C" {
+ fn c_explore_value() -> i32;
+}
+
+pub fn explore(
+) -> String {
+ unsafe {
+ other::explore(c_explore_value())
+ }
+}
diff --git a/test cases/rust/3 staticlib/test.json b/test cases/rust/3 staticlib/test.json
new file mode 100644
index 0000000..ca29225
--- /dev/null
+++ b/test cases/rust/3 staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/3 staticlib/value.c b/test cases/rust/3 staticlib/value.c
new file mode 100644
index 0000000..b71c806
--- /dev/null
+++ b/test cases/rust/3 staticlib/value.c
@@ -0,0 +1,5 @@
+int
+c_explore_value (void)
+{
+ return 42;
+}
diff --git a/test cases/rust/4 polyglot/meson.build b/test cases/rust/4 polyglot/meson.build
new file mode 100644
index 0000000..3601d5e
--- /dev/null
+++ b/test cases/rust/4 polyglot/meson.build
@@ -0,0 +1,9 @@
+project('rust and c polyglot executable', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+l = shared_library('stuff', 'stuff.rs', rust_crate_type: 'cdylib', install : true)
+e = executable('prog', 'prog.c', link_with : l, install : true)
+test('polyglottest', e)
diff --git a/test cases/rust/4 polyglot/prog.c b/test cases/rust/4 polyglot/prog.c
new file mode 100644
index 0000000..dbbd880
--- /dev/null
+++ b/test cases/rust/4 polyglot/prog.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void f();
+
+int main(void) {
+ printf("Hello from C!\n");
+ f();
+}
diff --git a/test cases/rust/4 polyglot/stuff.rs b/test cases/rust/4 polyglot/stuff.rs
new file mode 100644
index 0000000..ecf623c
--- /dev/null
+++ b/test cases/rust/4 polyglot/stuff.rs
@@ -0,0 +1,6 @@
+#![crate_name = "stuff"]
+
+#[no_mangle]
+pub extern fn f() {
+ println!("Hello from Rust!");
+}
diff --git a/test cases/rust/4 polyglot/test.json b/test cases/rust/4 polyglot/test.json
new file mode 100644
index 0000000..a8837a1
--- /dev/null
+++ b/test cases/rust/4 polyglot/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"},
+ {"type": "pdb", "file": "usr/bin/stuff"}
+ ]
+}
diff --git a/test cases/rust/5 polyglot static/clib.c b/test cases/rust/5 polyglot static/clib.c
new file mode 100644
index 0000000..366dbe5
--- /dev/null
+++ b/test cases/rust/5 polyglot static/clib.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+void hello_from_rust(void);
+
+static void hello_from_c(void) {
+ printf("Hello from C!\n");
+}
+
+void hello_from_both(void) {
+ hello_from_c();
+ hello_from_rust();
+}
diff --git a/test cases/rust/5 polyglot static/meson.build b/test cases/rust/5 polyglot static/meson.build
new file mode 100644
index 0000000..bed7977
--- /dev/null
+++ b/test cases/rust/5 polyglot static/meson.build
@@ -0,0 +1,18 @@
+project('static rust and c polyglot executable', 'c', 'rust')
+
+deps = [
+ meson.get_compiler('c').find_library('dl', required: false),
+ meson.get_compiler('c').find_library('m', required: false),
+ dependency('threads'),
+]
+
+extra_winlibs = meson.get_compiler('c').get_id() in ['msvc', 'clang-cl'] ? ['userenv.lib', 'ws2_32.lib', 'bcrypt.lib'] : []
+
+r = static_library('stuff', 'stuff.rs', rust_crate_type : 'staticlib')
+l = static_library('clib', 'clib.c', link_with : r, install : true)
+e = executable('prog', 'prog.c',
+ dependencies: deps,
+ link_with : l,
+ link_args: extra_winlibs,
+ install : true)
+test('polyglottest', e)
diff --git a/test cases/rust/5 polyglot static/prog.c b/test cases/rust/5 polyglot static/prog.c
new file mode 100644
index 0000000..0a8e0d1
--- /dev/null
+++ b/test cases/rust/5 polyglot static/prog.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void hello_from_both();
+
+int main(void) {
+ hello_from_both();
+}
diff --git a/test cases/rust/5 polyglot static/stuff.rs b/test cases/rust/5 polyglot static/stuff.rs
new file mode 100644
index 0000000..3777ae8
--- /dev/null
+++ b/test cases/rust/5 polyglot static/stuff.rs
@@ -0,0 +1,6 @@
+#![crate_name = "stuff"]
+
+#[no_mangle]
+pub extern "C" fn hello_from_rust() {
+ println!("Hello from Rust!");
+}
diff --git a/test cases/rust/5 polyglot static/test.json b/test cases/rust/5 polyglot static/test.json
new file mode 100644
index 0000000..cc0d2da
--- /dev/null
+++ b/test cases/rust/5 polyglot static/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libclib.a"}
+ ]
+}
diff --git a/test cases/rust/6 named staticlib/meson.build b/test cases/rust/6 named staticlib/meson.build
new file mode 100644
index 0000000..f91b7a1
--- /dev/null
+++ b/test cases/rust/6 named staticlib/meson.build
@@ -0,0 +1,5 @@
+project('rust static library', 'rust')
+
+l = static_library('named_stuff', 'stuff.rs', install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/6 named staticlib/prog.rs b/test cases/rust/6 named staticlib/prog.rs
new file mode 100644
index 0000000..856c4b7
--- /dev/null
+++ b/test cases/rust/6 named staticlib/prog.rs
@@ -0,0 +1,3 @@
+extern crate named_stuff;
+
+fn main() { println!("printing: {}", named_stuff::explore()); }
diff --git a/test cases/rust/6 named staticlib/stuff.rs b/test cases/rust/6 named staticlib/stuff.rs
new file mode 100644
index 0000000..9b36e57
--- /dev/null
+++ b/test cases/rust/6 named staticlib/stuff.rs
@@ -0,0 +1 @@
+pub fn explore() -> &'static str { "librarystring" }
diff --git a/test cases/rust/6 named staticlib/test.json b/test cases/rust/6 named staticlib/test.json
new file mode 100644
index 0000000..3ac3e0b
--- /dev/null
+++ b/test cases/rust/6 named staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libnamed_stuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/7 private crate collision/meson.build b/test cases/rust/7 private crate collision/meson.build
new file mode 100644
index 0000000..81b6aab
--- /dev/null
+++ b/test cases/rust/7 private crate collision/meson.build
@@ -0,0 +1,5 @@
+project('rust private crate collision', 'rust')
+
+l = static_library('rand', 'rand.rs', install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/7 private crate collision/prog.rs b/test cases/rust/7 private crate collision/prog.rs
new file mode 100644
index 0000000..b9a30f1
--- /dev/null
+++ b/test cases/rust/7 private crate collision/prog.rs
@@ -0,0 +1,3 @@
+extern crate rand;
+
+fn main() { println!("printing: {}", rand::explore()); }
diff --git a/test cases/rust/7 private crate collision/rand.rs b/test cases/rust/7 private crate collision/rand.rs
new file mode 100644
index 0000000..8a3d427
--- /dev/null
+++ b/test cases/rust/7 private crate collision/rand.rs
@@ -0,0 +1,4 @@
+// use a name that collides with one of the rustc_private libraries
+#![crate_name = "rand"]
+
+pub fn explore() -> &'static str { "librarystring" }
diff --git a/test cases/rust/7 private crate collision/test.json b/test cases/rust/7 private crate collision/test.json
new file mode 100644
index 0000000..e35f6ff
--- /dev/null
+++ b/test cases/rust/7 private crate collision/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/librand.rlib"}
+ ]
+}
diff --git a/test cases/rust/8 many files/foo.rs b/test cases/rust/8 many files/foo.rs
new file mode 100644
index 0000000..0899dc0
--- /dev/null
+++ b/test cases/rust/8 many files/foo.rs
@@ -0,0 +1,3 @@
+pub fn bar() -> () {
+ println!("Hello, world!");
+}
diff --git a/test cases/rust/8 many files/main.rs b/test cases/rust/8 many files/main.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/8 many files/main.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/8 many files/meson.build b/test cases/rust/8 many files/meson.build
new file mode 100644
index 0000000..1d906b3
--- /dev/null
+++ b/test cases/rust/8 many files/meson.build
@@ -0,0 +1,3 @@
+project('manyfiles', 'rust')
+
+test('manyfiles', executable('manyfiles', 'main.rs', 'foo.rs'))
diff --git a/test cases/rust/9 unit tests/meson.build b/test cases/rust/9 unit tests/meson.build
new file mode 100644
index 0000000..b649abb
--- /dev/null
+++ b/test cases/rust/9 unit tests/meson.build
@@ -0,0 +1,43 @@
+project('rust unit tests', 'rust')
+
+t = executable(
+ 'rust_test',
+ ['test.rs'],
+ rust_args : ['--test'],
+)
+
+test(
+ 'rust test (should fail)',
+ t,
+ protocol : 'rust',
+ suite : ['foo'],
+ should_fail : true,
+)
+
+test(
+ 'rust test (should pass)',
+ t,
+ args : ['--skip', 'test_add_intentional_fail'],
+ protocol : 'rust',
+ suite : ['foo'],
+)
+
+
+test(
+ 'rust test (should skip)',
+ t,
+ args : ['--skip', 'test_add'],
+ 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/test.rs b/test cases/rust/9 unit tests/test.rs
new file mode 100644
index 0000000..0225be5
--- /dev/null
+++ b/test cases/rust/9 unit tests/test.rs
@@ -0,0 +1,24 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_add() {
+ assert_eq!(add(1, 2), 3);
+ }
+
+ #[test]
+ fn test_add_intentional_fail() {
+ assert_eq!(add(1, 2), 5);
+ }
+
+ #[test]
+ #[ignore]
+ fn test_add_intentional_fail2() {
+ assert_eq!(add(1, 7), 5);
+ }
+}
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);
+}