Statically link executable with glibc

It is possible from my understanding to have a fully static binary by using musl-libc.

Is it possible to do the same thing with glibc and if yes how?

1 Like

it should be possible (might be just a matter of passing -static to the linker), though statically linking with glibc is usually advised against because of

2 Likes

I have added -static to .cargo/config:

[build]
rustflags = [
	"-C", "link-arg=-static",
]

However I get an error which I am not quite sure how to fix:

  = note: /nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: /nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0/lib/gcc/x86_64-unknown-linux-gnu/7.4.0/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object

and here is the end of the link command:

"-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil" "-shared" "-static"

it seems that dynamic linking and static linking are done at the same time. I don't know how to fix this.

ah crap, yea, cargo or rustc passes all kinds of things automatically, the only way to override that might be to make changes to their source

say, you really want this, for sake of demonstration—what seems to work is to make a staticlib crate

Cargo.toml:

…
[lib]
name = "statictest"
crate-type = ["staticlib"]

src/lib.rs:

#[no_mangle]
pub extern "C" fn main() {
    println!("Hell world");
}
$ cargo build --release
$ gcc -static target/release/libstatictest.a -o statictest -lpthread -ldl
$ ldd ./statictest
        not a dynamic executable
$ ./statictest
Hell world

(to be clear: it is unsafe to ship these executables to systems that don't have exactly the same glibc, as glibc will be dynamically loading nss modules internally and there might be ABI conflicts, even silent crashy ones, although this likely only matters if you do DNS lookups)

2 Likes

Well, I managed to get it working.

This seems to be quite a dirty solution, especially to what I am used to in the rust world.

Is this a bug? Should/could this be reported?

Yes this could be better. You can report it as a feature request, but it would be more convincing if you detail why you want this at all, i.e. use cases. Why do you need to static link with glibc but can't do so with musl?

The reason I wanted to use glibc instead of musl is that glibc can sometimes be more performant though bigger.

Also should this be reported/requested to cargo or rustc?

From what I can tell this should be fixed using +crt-static as described in the reference:

https://doc.rust-lang.org/reference/linkage.html