用gcc链接由Rust编译的动态库

5
我将非Rust程序编译成动态库并将其与现有的C++项目进行链接。我们的C++项目使用gcc进行编译(相对较旧的gcc 4.8.2版本,但我也尝试了gcc 7.3.0版本,出现了相同问题)。以下是问题的一个简单示例: src/lib.rs
#[no_mangle]
pub unsafe extern "C" fn hello() {
  println!("Hello World, Rust here!");
}

Cargo.toml

[package]
name = "gcc-linking"
version = "0.1.0"
authors = ..
edition = "2018"

[lib]
crate-type = ["dylib"]

[dependencies]

hello.cpp:

extern "C" void hello();

int main() {

    hello();
    return 0;
}

现在,当我使用 clang 进行链接时,一切都很好:
cargo build --lib
clang -L target/debug -l gcc_linking hello.cpp -o hello
LD_LIBRARY_PATH=target/debug:$LD_LIBRARY_PATH ./hello

正如预期的那样,这会导致:

Hello World, Rust here!

但是,如果我尝试将其与gcc链接,我会得到以下链接错误:

gcc -L target/debug -l gcc_linking hello.cpp -o hello

输出:

/tmp/ccRdGJOK.o: In function `main':
hello.cpp:(.text+0x5): undefined reference to `hello'
collect2: error: ld returned 1 exit status

看动态库:

# objdump -T output
0000000000043f60 g    DF .text  0000000000000043  Base        hello
# nm -gC output
0000000000043f60 T hello

我怀疑这个问题与函数名称的破坏有关,但我不知道如何解决它。
有什么想法吗?

2
你试过将crate-type设置为"cdylib"而不是"dylib"吗? - E net4
"cdylib" 有同样的问题。 - Stefan
在我的Mac上,使用gcc 8.2.0可以正常工作。 - olivecoder
3
尝试将-l gcc_linking放在gcc命令行中hello.cpp之后。 - Jmb
哦,将hello.cpp后面加上-l gcc_linking确实起作用了。非常感谢@Jmb。 - Stefan
1个回答

0

正如@Jmb所建议的那样,解决方案是改变gcc参数的顺序,并在C++文件之后列出共享库:

gcc -L target/debug hello.cpp -l gcc_linking -o hello

下次使用CMake吧 ;) - jaques-sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接