at54321
at54321

Reputation: 11708

Why is a Rust app binary "dynamically linked"?

I got curious and decided to run the file command on a Rust app I compiled for Linux (Ubuntu 20.04). Why is the executable file "dynamically linked"? I though by default Rust binaries were statically linked.

$ 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

I tested with a few Rust bin apps, the last being a fresh hello-world app created via cargo new ... and simply built with cargo build --release. I also tested with two different linkers: the default and LLD. In all cases the file command displayed "dynamically linked".

Upvotes: 1

Views: 952

Answers (1)

typetetris
typetetris

Reputation: 4867

Rust still links to GNU lib c and it is discouraged to statically link gnu libc: Why is statically linking glibc discouraged?

$ 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)

So statically linking glibc would be a poor default choice.

You can link your rust programs completely static, easiest is probably to just use the musl target (at least on 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

But you open another can of worms here:

Upvotes: 4

Related Questions