如何在链接时始终包含 Rust 依赖项?

How do I always include a Rust dependency when linking?

我正在尝试使用 Fortanix SGX 框架 运行 飞地中的 libdvdcss,但是 linker 有问题。

我围绕 libdvdcss 创建了一个简单的 FFI 包装器,它在 Linux 上正常执行时工作正常(没有 SGX 并且全局安装了 libdvdcss)。当我 运行 它与 Getting started 页面上指定的目标 x86_64-fortanix-unknown-sgx 时它不起作用,因为 linker 抱怨许多丢失的符号,尤其是 malloc

据我了解,问题是 SGX 中没有 libc,因此我需要手动包含 rs-libc,这基本上是在 SGX 中使用的 libc。 rs-libc crate 包含 C、ASM 和一些 Rust 代码(主要用于 malloc)。因此我的 Cargo.toml:

[dependencies]
rs-libc = "0.2.3"

我发现这还不够,我必须提供以下 build.rs 来手动告诉 linker link libc.a 来自 rs-libc 箱子也是。

pub fn main() {
    println!("cargo:rustc-link-search=/home/me/dev/libdvdcss/.libs");  // Will be changed later
    println!("cargo:rustc-link-lib=static=dvdcss");
    println!("cargo:rustc-link-lib=static=c");
}

这修复了一些 strlen 等错误,但未找到 mallocfree。我认为问题在于它们不是从 C 源文件编译的,而是在 alloc.rs 中编译的。我还看到这个源文件被编译成 target/x86_64-fortanix-unknown-sgx/debug/deps/librs_libc-04111db022dd517f.rlib 中的 Rust 库并包含符号:

rs_libc-04111db022dd517f.rs_libc.53f0fd72-cgu.5.rcgu.o:
0000000000000000 T calloc
0000000000000000 T free
0000000000000000 W __llvm_lvi_thunk_r11
0000000000000000 T malloc
0000000000000000 T realloc
0000000000000000 V __rustc_debug_gdb_scripts_section__
                 U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GTalloc_zeroed17ha722ea369ab2dac9E
                 U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GTalloc17h561d825df0f2dfa8E
                 U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GTdealloc17hbbda0b3d0a1f9d67E
                 U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GTrealloc17hf76d62802e46847bE
                 U _ZN4core3ptr4read17hc3470c4a404ff082E
                 U _ZN4core3ptr5write17ha0bb4d6cbfed535eE
                 U _ZN4core5alloc6layout6Layout25from_size_align_unchecked17h074422ae6f6459f7E
                 U _ZN4core9panicking5panic17hde9db97a7382bd28E

不幸的是,这个文件似乎没有包含在最后的 linker 命令中。我认为这是因为在我的 Rust 应用程序中没有找到这个库的用法,因此它被优化了。

有没有办法包含它?

添加一个 extern crate rs_libc; 到你 crate 的根应该可以解决问题。必须将使用 extern crate 声明的依赖项提供给链接器是强制性的。在 rust 2018 及更高版本中,当且仅当您使用该 crate 的一个或多个符号时,编译器才会将适当的声明隐式添加到您的 crate(rust 2015 要求明确添加 extern crate )。有关详细信息,请参阅 rust reference 中的部分。