Skip to content

Commit 251ef35

Browse files
committed
rust: rlib/staticlib should not link with C libraries
1 parent f469bd4 commit 251ef35

File tree

8 files changed

+57
-0
lines changed

8 files changed

+57
-0
lines changed

mesonbuild/backend/ninjabackend.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,13 @@ def generate_rust_target(self, target: build.BuildTarget) -> None:
19971997

19981998
# Link a C ABI library
19991999

2000+
# rlib/staticlib does not need to link with C libraries, it would
2001+
# cause rustc to include .o objects contained in C static libraries
2002+
# inside the archive. That would in turn cause multiple definition
2003+
# of symbols in the case of a diamond dependency graph.
2004+
if isinstance(target, build.StaticLibrary):
2005+
continue
2006+
20002007
if isinstance(d, build.StaticLibrary):
20012008
external_deps.extend(d.external_deps)
20022009

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
int c_func(void);
2+
int c_func(void) {
3+
return 123;
4+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
int r3(void);
2+
3+
int main_func(void) {
4+
return r3() == 246 ? 0 : 1;
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Regression test for a diamond dependency graph:
2+
# ┌►R1┐
3+
# main-►R3─┤ ├─►C1
4+
# └►R2┘
5+
# Both libr1.rlib and libr2.rlib used to contain func.c.o. That was causing
6+
# libr3.rlib to have duplicated func.c.o and then libmain.so failed to link:
7+
# multiple definition of `c_func'.
8+
9+
libc1 = static_library('c1', 'func.c')
10+
libr1 = static_library('r1', 'r1.rs', link_with: libc1)
11+
libr2 = static_library('r2', 'r2.rs', link_with: libc1)
12+
libr3 = static_library('r3', 'r3.rs',
13+
link_with: [libr1, libr2],
14+
rust_abi: 'c',
15+
)
16+
17+
shared_library('main', 'main.c', link_whole: [libr3])
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern "C" {
2+
fn c_func() -> i32;
3+
}
4+
5+
pub fn r1() -> i32 {
6+
unsafe {
7+
c_func()
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern "C" {
2+
fn c_func() -> i32;
3+
}
4+
5+
pub fn r2() -> i32 {
6+
unsafe {
7+
c_func()
8+
}
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[no_mangle]
2+
pub fn r3() -> i32 {
3+
r1::r1() + r2::r2()
4+
}

test cases/rust/20 transitive dependencies/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ exe = executable('footest', 'foo.c',
2525
link_with: foo,
2626
)
2727
test('footest', exe)
28+
29+
subdir('diamond')

0 commit comments

Comments
 (0)