diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 8ae54754b639..9283bca97f96 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1299,6 +1299,8 @@ def get_dependencies_recurse(self, result: OrderedSet[Target], include_internals for t in self.link_targets: if t in result: continue + if isinstance(t, SharedLibrary) and t.rust_crate_type == 'proc-macro': + continue if include_internals or not t.is_internal(): result.add(t) if isinstance(t, StaticLibrary): diff --git a/test cases/rust/20 transitive dependencies/foo.c b/test cases/rust/20 transitive dependencies/foo.c new file mode 100644 index 000000000000..e40878a87709 --- /dev/null +++ b/test cases/rust/20 transitive dependencies/foo.c @@ -0,0 +1,8 @@ +#include + +uint32_t foo_rs(void); + +int main(void) +{ + return foo_rs() == 42 ? 0 : 1; +} diff --git a/test cases/rust/20 transitive dependencies/foo.rs b/test cases/rust/20 transitive dependencies/foo.rs new file mode 100644 index 000000000000..8e3863853f9d --- /dev/null +++ b/test cases/rust/20 transitive dependencies/foo.rs @@ -0,0 +1,9 @@ +extern crate pm; +use pm::make_answer; + +make_answer!(); + +#[no_mangle] +pub fn foo_rs() -> u32 { + answer() +} diff --git a/test cases/rust/20 transitive dependencies/meson.build b/test cases/rust/20 transitive dependencies/meson.build index 2f378f88fecd..e5354b8f6f13 100644 --- a/test cases/rust/20 transitive dependencies/meson.build +++ b/test cases/rust/20 transitive dependencies/meson.build @@ -1,4 +1,4 @@ -project('transitive dependencies', 'rust', +project('transitive dependencies', 'rust', 'c', version : '1.0.0', meson_version : '>= 1.0.0', default_options : ['rust_std=2018'], @@ -10,3 +10,18 @@ subdir('libb') main = executable('main', 'main.rs', dependencies : [libb_dep], ) + +# Since foo-rs is a static library, its dependencies are normally added to +# footest link command. However, since pm is a proc-macro, footest should not +# link with it. In native build this is an harmless overlinking, but in cross +# building foo and pm are for different arch and it would fail to link. +rust = import('rust') +pm = rust.proc_macro('pm', 'proc.rs') +foo = static_library('foo-rs', 'foo.rs', + rust_abi: 'c', + link_with: pm, +) +exe = executable('footest', 'foo.c', + link_with: foo, +) +test('footest', exe) diff --git a/test cases/rust/20 transitive dependencies/proc.rs b/test cases/rust/20 transitive dependencies/proc.rs new file mode 100644 index 000000000000..53935e45d17f --- /dev/null +++ b/test cases/rust/20 transitive dependencies/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() +}