为什么 Rust 应用程序二进制 "dynamically linked"?

Why is a Rust app binary "dynamically linked"?

我很好奇并决定在我为 Linux (Ubuntu 20.04) 编译的 Rust 应用程序上 运行 命令 file。为什么可执行文件是“动态链接”的?我虽然默认情况下 Rust 二进制文件是静态链接的。

$ file my_hello_world_app
my_hello_world_app: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[xxHash]=5ddb20be333a274e, with debug_info, not stripped

我测试了几个 Rust bin 应用程序,最后一个是通过 cargo new ... 创建的新的 hello-world 应用程序,并简单地用 cargo build --release 构建。我还测试了两个不同的链接器:默认链接器和 LLD。在所有情况下,file 命令都显示“动态链接”。

Rust 仍然 links 到 GNU lib c and it is discouraged to statically link gnu libc:

$ ldd target/release/hello
        linux-vdso.so.1 (0x00007ffd4c1ed000)
        libgcc_s.so.1 => /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/libgcc_s.so.1 (0x00007f24c760e000)
        libpthread.so.0 => /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/libpthread.so.0 (0x00007f24c75ed000)
        libm.so.6 => /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/libm.so.6 (0x00007f24c74aa000)
        libdl.so.2 => /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/libdl.so.2 (0x00007f24c74a5000)
        libc.so.6 => /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/libc.so.6 (0x00007f24c72e4000)
        /nix/store/v8q6nxyppy1myi3rxni2080bv8s9jxiy-glibc-2.32-40/lib/ld-linux-x86-64.so.2 => /nix/store/gk42f59363p82rg2wv2mfy71jn5w4q4c-glibc-2.32-48/lib64/ld-linux-x86-64.so.2 (0x00007f24c766f000)

所以静态 linking glibc 将是一个糟糕的默认选择。

您可以 link 您的 rust 程序完全静态,最简单的可能是只使用 musl 目标(至少在 linux 上):

$ cargo build --target x86_64-unknown-linux-musl --release
    Finished release [optimized] target(s) in 0.00s

$ ldd target/x86_64-unknown-linux-musl/release/hello
        statically linked

但是你在这里打开了另一个蠕虫罐头: