如何将Rust依赖crate打包为共享库实现动态链接?
Rust 多CGI二进制共享公共依赖为动态库的实现方案
完全可以实现将公共依赖打包成共享对象,让多个二进制文件动态链接,避免重复编译和体积膨胀,不用手动逐个处理递归依赖,用Cargo工作区就能高效搞定:
步骤1:创建共享依赖库项目
新建一个专门的Rust库项目(比如叫shared_deps),在它的Cargo.toml里配置为动态库类型,并加入所有需要共享的公共依赖:
[package] name = "shared_deps" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] # 指定编译为C兼容的动态库 [dependencies] # 在这里添加所有CGI二进制共用的依赖,比如: tokio = { version = "1.35", features = ["rt", "net"] } serde = { version = "1.0", features = ["derive"] } anyhow = "1.0" # 其他你用到的公共crate...
如果你的CGI二进制需要直接使用这些依赖的API,在shared_deps的src/lib.rs里把它们重新导出:
pub use tokio; pub use serde; pub use anyhow; // 导出其他需要直接调用的API
步骤2:配置CGI二进制项目
把你的binaryA、binaryB和shared_deps放到同一个Cargo工作区里(工作区根目录的Cargo.toml):
[workspace] members = [ "shared_deps", "binaryA", "binaryB", ]
然后在每个二进制项目的Cargo.toml里,依赖shared_deps,同时确保公共依赖不会被静态编译进来:
[dependencies] shared_deps = { path = "../shared_deps" } # 如果二进制里需要直接用公共依赖的API,直接通过shared_deps引用,比如`use shared_deps::tokio;` # 不要单独重复声明这些公共依赖,避免静态链接
步骤3:编译与部署
- 先编译共享库:
cargo build --release --target <你的嵌入式平台目标三元组>
编译完成后,在target/<目标三元组>/release目录下会生成libshared_deps.so(Linux平台)。
- 编译所有CGI二进制:
cargo build --release --package binaryA --target <目标三元组> cargo build --release --package binaryB --target <目标三元组>
Cargo会自动让二进制链接到shared_deps动态库,不会再静态编译那些公共依赖。
- 部署到嵌入式设备:
- 将
libshared_deps.so放到设备的系统库路径(比如/usr/lib),或者设置LD_LIBRARY_PATH环境变量指向它所在的目录 - 将
binaryA、binaryB放到CGI脚本目录(比如/var/www/cgi-bin)
注意事项
- Rust ABI兼容性:共享库和所有二进制必须用同一版本的Rust编译器编译,因为Rust的私有ABI不稳定,跨版本编译可能导致运行错误
- 目标平台一致性:确保所有编译的目标三元组完全一致,比如
armv7-unknown-linux-gnueabihf,避免平台不兼容 - 依赖版本统一:工作区会自动统一所有依赖的版本,不用手动维护,避免版本冲突
- 最小化体积:编译时可以启用
strip去掉符号表,进一步缩小文件体积:cargo build --release --target <目标三元组> --profile release-with-debug(或者手动用strip命令处理生成的文件)
内容的提问来源于stack exchange,提问作者Schievel
相关产品推荐
相关产品推荐

