Skip to content

Commit

Permalink
rust: Add linkdirs of indirect Rust dependencies to the target's link…
Browse files Browse the repository at this point in the history
…dirs

rustc requires all the linkdirs to indirect dependencies to be able to
find them, but doesn't require them to be provided as `--extern` in
addition. The latter would also easily lead to name conflicts.

Fixes #11694
  • Loading branch information
sdroege committed Apr 23, 2023
1 parent 01420bf commit 04ce8c6
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 0 deletions.
23 changes: 23 additions & 0 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,27 @@ def _get_rust_dependency_name(self, target: build.BuildTarget, dependency: LibTy
# in Rust
return target.rust_dependency_map.get(dependency.name, dependency.name).replace('-', '_')

def _add_rust_indirect_dependency_linkdirs(self, linkdirs: OrderedSet[str], dependency: LibTypes):
# Add all the linkdirs of indirect dependencies to the linkdirs if
# they're rlib/proc-macro/dylib dependencies. rustc requires this to
# be able to find the indirect dependencies during the build.
indirect_rust_deps = [dependency]

# Instead of actually recursing over the dependencies use a stack here
while indirect_rust_deps:
indirect_dep = indirect_rust_deps.pop()
if not indirect_dep.uses_rust() or indirect_dep.rust_crate_type in ['staticlib', 'cdylib']:
continue
for d in indirect_dep.kwargs.get('dependencies', []):
if not hasattr(d, 'libraries'):
continue
indirect_rust_deps += d.libraries
indirect_rust_deps += d.whole_libraries
indirect_rust_deps += indirect_dep.link_targets
indirect_rust_deps += indirect_dep.link_whole_targets

linkdirs.add(indirect_dep.subdir)

def generate_rust_target(self, target: build.BuildTarget) -> None:
rustc = target.compilers['rust']
# Rust compiler takes only the main file as input and
Expand Down Expand Up @@ -1945,6 +1966,7 @@ def generate_rust_target(self, target: build.BuildTarget) -> None:
d_name = self._get_rust_dependency_name(target, d)
args += ['--extern', '{}={}'.format(d_name, os.path.join(d.subdir, d.filename))]
project_deps.append(RustDep(d_name, self.rust_crates[d.name].order))
self._add_rust_indirect_dependency_linkdirs(linkdirs, d)
elif isinstance(d, build.StaticLibrary):
# Rustc doesn't follow Meson's convention that static libraries
# are called .a, and import libraries are .lib, so we have to
Expand Down Expand Up @@ -1984,6 +2006,7 @@ def generate_rust_target(self, target: build.BuildTarget) -> None:
d_name = self._get_rust_dependency_name(target, d)
args += ['--extern', '{}={}'.format(d_name, os.path.join(d.subdir, d.filename))]
project_deps.append(RustDep(d_name, self.rust_crates[d.name].order))
self._add_rust_indirect_dependency_linkdirs(linkdirs, d)
else:
if rustc.linker.id in {'link', 'lld-link'}:
if verbatim:
Expand Down
3 changes: 3 additions & 0 deletions test cases/rust/20 transitive dependencies/liba/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn foo() -> i32 {
123
}
5 changes: 5 additions & 0 deletions test cases/rust/20 transitive dependencies/liba/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
liba = static_library('liba', 'lib.rs',
rust_crate_type : 'rlib',
)

liba_dep = declare_dependency(link_with : liba)
3 changes: 3 additions & 0 deletions test cases/rust/20 transitive dependencies/libb/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn bar() -> i32 {
2 * liba::foo()
}
6 changes: 6 additions & 0 deletions test cases/rust/20 transitive dependencies/libb/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
libb = static_library('libb', 'lib.rs',
rust_crate_type : 'rlib',
dependencies : [liba_dep],
)

libb_dep = declare_dependency(link_with : libb)
3 changes: 3 additions & 0 deletions test cases/rust/20 transitive dependencies/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("{}", libb::bar());
}
12 changes: 12 additions & 0 deletions test cases/rust/20 transitive dependencies/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
project('transitive dependencies', 'rust',
version : '1.0.0',
meson_version : '>= 1.0.0',
default_options : ['rust_std=2018'],
)

subdir('liba')
subdir('libb')

main = executable('main', 'main.rs',
dependencies : [libb_dep],
)

0 comments on commit 04ce8c6

Please sign in to comment.