如何构建一个不依赖共享库的Rust应用程序?

10

我该如何编译Rust应用程序而不需要加载共享库?

我尝试了什么:

ex.rs

fn main() {
  println!("Try to compile me statically!");
}

根据https://rust-lang.github.io/rfcs/1721-crt-static.html,我进行了以下操作:

$ rustc -C target-feature=+crt-static ./ex.rs
$ ldd ./ex
    linux-vdso.so.1 (0x00007ffc4e3ef000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc30b8c4000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc30b6bc000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc30b49d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc30b285000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc30ae94000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fc30bcfb000)

为什么不静态编译libc?如何避免链接所有其他共享库?

1
据我所知,标准的libc(如glibc)并不是为静态链接而设计的。您可以尝试使用musl代替。 - Cerberus
@Cerberus但我的目标项目使用的是actix箱,它不支持musl。如何克服这个问题? - unegare
1个回答

11

完全静态二进制文件的MUSL支持
默认情况下,Rust会静态链接所有Rust代码。但是,如果使用标准库,则会动态链接到系统的libc实现。

如果您想要一个100%静态的二进制文件,则可以在Linux上使用MUSL libc:

rustup target add x86_64-unknown-linux-musl 

RUSTFLAGS='-C link-arg=-s' cargo build --release --target x86_64-unknown-linux-musl

main.rs 文件:

use actix_web::{web, App, HttpServer, Responder};

async fn index(info: web::Path<(String, u32)>) -> impl Responder {
    format!("Hello {}! id:{}", info.0, info.1)
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(web::resource("/{name}/{id}/index.html").to(index)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

Cargo.toml 文件:

[profile.release]
opt-level = 's'  # Optimize for size.
lto = true # Link Time Optimization (LTO)
# codegen-units = 1 # Set this to 1 to allow for maximum size reduction optimizations:
# panic = 'abort' # removes the need for this extra unwinding code.

[dependencies]
actix-web = "2.0.0" # Actix web is a simple, pragmatic and extremely fast web framework for Rust.
actix-rt = "1.0.0"  # Actix runtime

Rust 平台支持


1
谢谢!自 actix2.0 版本以来,它似乎已经改变了。 - unegare

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