Rust链接时如何强制包含依赖 解决Fortanix SGX下malloc符号缺失
解决方案
- 方法1:强制引用符号避免优化剔除
在你的Rust入口文件(如main.rs/lib.rs)中添加如下代码,通过#[used]属性通知编译器保留符号引用,阻止死代码优化把rs-libc的相关编译单元删掉:
extern "C" { fn malloc(size: usize) -> *mut u8; fn free(ptr: *mut u8); fn calloc(nmemb: usize, size: usize) -> *mut u8; fn realloc(ptr: *mut u8, size: usize) -> *mut u8; } #[used] #[no_mangle] static __FORCE_LINK_RS_LIBC_ALLOC: [unsafe extern "C" fn(usize) -> *mut u8; 1] = [malloc];
这段代码会强制保留对malloc的引用,链接器会自动拉取rs-libc中包含malloc实现的编译单元,剩余的calloc、free、realloc属于同一个编译单元,会一起被链接进来。
- 方法2:通过链接器参数强制全库链接
无需修改业务代码,直接在build.rs中添加链接参数,强制将整个rs-libc库纳入链接流程:
pub fn main() { // 保留你原有的配置 println!("cargo:rustc-link-search=/home/me/dev/libdvdcss/.libs"); println!("cargo:rustc-link-lib=static=dvdcss"); println!("cargo:rustc-link-lib=static=c"); // 新增针对SGX目标的全量链接参数 if std::env::var("TARGET").unwrap() == "x86_64-fortanix-unknown-sgx" { println!("cargo:rustc-link-arg=-Wl,--whole-archive,-lrs_libc,--no-whole-archive"); } }
--whole-archive参数会通知链接器不做裁剪,把指定静态库的所有编译单元全部加入最终产物,自然就包含了alloc.rs的实现。
- 方法3:确认rs-libc功能特性开启
部分版本的rs-libc默认不会编译alloc相关实现,需要在Cargo.toml中显式开启对应feature:
[dependencies] rs-libc = { version = "0.2.3", features = ["alloc"] }
问题根源说明
你遇到的问题是Rust的依赖裁剪机制导致的:只有被Rust代码显式引用的依赖库编译单元才会被纳入最终链接流程。rs-libc中C代码实现的strlen等函数属于你链接的静态libc.a,所以能正常找到;而Rust实现的malloc等函数在单独的rlib编译单元中,没有被Rust代码引用就直接被裁剪掉了,因此链接时找不到对应符号。
内容的提问来源于stack exchange,提问作者Hellstorm
相关产品推荐
相关产品推荐

