rust: recursively pull proc-macro deps for rust targets

aee941559 ("rust: recursively pull proc-macro dependencies as well")
had to be reverted (in a66cb97e8) because it broke Mesa cross
compilation.  This happened because a C shared library was linked with
a Rust C-ABI static library, which caused it to inherit the proc macro
dependency the Rust static library was linked with.

The right way to handle this is for only Rust targets to inherit proc
macro dependencies from static libraries they link with.  A Rust
executable, library, or whatever will need the proc macros its Rust
dependencies use, as illustrated in the test case that I've
reintroduced here.

I've verified that Mesa still cross compiles correctly with this
change.  The same failure was also identified by the "rust/21
transitive dependencies" test case, but only when cross compiling, so
it wasn't caught by CI.

Co-authored-by: Xavier Claessens <xavier.claessens@collabora.com>
pull/12487/head
Alyssa Ross 7 months ago committed by Xavier Claessens
parent 6e20022295
commit a05f6a260e
  1. 10
      mesonbuild/build.py
  2. 8
      test cases/rust/18 proc-macro/lib.rs
  3. 11
      test cases/rust/18 proc-macro/meson.build
  4. 1
      test cases/rust/18 proc-macro/subdir/meson.build
  5. 7
      test cases/rust/18 proc-macro/transitive-proc-macro.rs
  6. 1
      test cases/rust/21 transitive dependencies/meson.build

@ -1292,10 +1292,10 @@ class BuildTarget(Target):
if t not in result: if t not in result:
result.add(t) result.add(t)
if isinstance(t, StaticLibrary): if isinstance(t, StaticLibrary):
t.get_dependencies_recurse(result) t.get_dependencies_recurse(result, include_proc_macros = self.uses_rust())
return result return result
def get_dependencies_recurse(self, result: OrderedSet[BuildTargetTypes], include_internals: bool = True) -> None: def get_dependencies_recurse(self, result: OrderedSet[BuildTargetTypes], include_internals: bool = True, include_proc_macros: bool = False) -> None:
# self is always a static library because we don't need to pull dependencies # self is always a static library because we don't need to pull dependencies
# of shared libraries. If self is installed (not internal) it already # of shared libraries. If self is installed (not internal) it already
# include objects extracted from all its internal dependencies so we can # include objects extracted from all its internal dependencies so we can
@ -1304,14 +1304,14 @@ class BuildTarget(Target):
for t in self.link_targets: for t in self.link_targets:
if t in result: if t in result:
continue continue
if t.rust_crate_type == 'proc-macro': if not include_proc_macros and t.rust_crate_type == 'proc-macro':
continue continue
if include_internals or not t.is_internal(): if include_internals or not t.is_internal():
result.add(t) result.add(t)
if isinstance(t, StaticLibrary): if isinstance(t, StaticLibrary):
t.get_dependencies_recurse(result, include_internals) t.get_dependencies_recurse(result, include_internals, include_proc_macros)
for t in self.link_whole_targets: for t in self.link_whole_targets:
t.get_dependencies_recurse(result, include_internals) t.get_dependencies_recurse(result, include_internals, include_proc_macros)
def get_source_subdir(self): def get_source_subdir(self):
return self.subdir return self.subdir

@ -0,0 +1,8 @@
extern crate proc_macro_examples;
use proc_macro_examples::make_answer;
make_answer!();
pub fn func() -> u32 {
answer()
}

@ -31,3 +31,14 @@ main = executable(
) )
test('main_test2', main) test('main_test2', main)
subdir('subdir')
staticlib = static_library('staticlib', 'lib.rs',
link_with: pm_in_subdir,
rust_dependency_map : {'proc_macro_examples3' : 'proc_macro_examples'}
)
executable('transitive-proc-macro', 'transitive-proc-macro.rs',
link_with: staticlib,
)

@ -0,0 +1 @@
pm_in_subdir = rust.proc_macro('proc_macro_examples3', '../proc.rs')

@ -0,0 +1,7 @@
extern crate staticlib;
use staticlib::func;
fn main() {
assert_eq!(42, func());
}

@ -21,6 +21,7 @@ foo = static_library('foo-rs', 'foo.rs',
rust_abi: 'c', rust_abi: 'c',
link_with: pm, link_with: pm,
) )
shared_library('shared', 'foo.c', link_with : foo)
exe = executable('footest', 'foo.c', exe = executable('footest', 'foo.c',
link_with: foo, link_with: foo,
) )

Loading…
Cancel
Save