Skip to content

Commit

Permalink
rust: rlib/staticlib should not link with C libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
xclaesse committed Nov 7, 2023
1 parent f469bd4 commit 251ef35
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 0 deletions.
7 changes: 7 additions & 0 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1997,6 +1997,13 @@ def generate_rust_target(self, target: build.BuildTarget) -> None:

# Link a C ABI library

# rlib/staticlib does not need to link with C libraries, it would
# cause rustc to include .o objects contained in C static libraries
# inside the archive. That would in turn cause multiple definition
# of symbols in the case of a diamond dependency graph.
if isinstance(target, build.StaticLibrary):
continue

if isinstance(d, build.StaticLibrary):
external_deps.extend(d.external_deps)

Expand Down
4 changes: 4 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/func.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int c_func(void);
int c_func(void) {
return 123;
}
5 changes: 5 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int r3(void);

int main_func(void) {
return r3() == 246 ? 0 : 1;
}
17 changes: 17 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Regression test for a diamond dependency graph:
# ┌►R1┐
# main-►R3─┤ ├─►C1
# └►R2┘
# Both libr1.rlib and libr2.rlib used to contain func.c.o. That was causing
# libr3.rlib to have duplicated func.c.o and then libmain.so failed to link:
# multiple definition of `c_func'.

libc1 = static_library('c1', 'func.c')
libr1 = static_library('r1', 'r1.rs', link_with: libc1)
libr2 = static_library('r2', 'r2.rs', link_with: libc1)
libr3 = static_library('r3', 'r3.rs',
link_with: [libr1, libr2],
rust_abi: 'c',
)

shared_library('main', 'main.c', link_whole: [libr3])
9 changes: 9 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/r1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extern "C" {
fn c_func() -> i32;
}

pub fn r1() -> i32 {
unsafe {
c_func()
}
}
9 changes: 9 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/r2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extern "C" {
fn c_func() -> i32;
}

pub fn r2() -> i32 {
unsafe {
c_func()
}
}
4 changes: 4 additions & 0 deletions test cases/rust/20 transitive dependencies/diamond/r3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[no_mangle]
pub fn r3() -> i32 {
r1::r1() + r2::r2()
}
2 changes: 2 additions & 0 deletions test cases/rust/20 transitive dependencies/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ exe = executable('footest', 'foo.c',
link_with: foo,
)
test('footest', exe)

subdir('diamond')

0 comments on commit 251ef35

Please sign in to comment.