Can I force a static linking of glibc in a cross-compiled binary?

I am cross-compiling for Raspberry pi. There was a recent change to Rust-Analyzer that required me to upgrade my local computer's glibc to compile. Now, the binaries I create for Raspberry Pi are requiring that I have the same glibc installed on the Raspberry Pi; which of course, is a pretty big headache and I can't assume that an end user will be able to figure all that out just to run my program.

How do I get a statically linked glibc? Because right now I cannot compile a binary that will run on Raspbian because Raspbian is tied to the older glibc library.

I REALLY wish that rust-analyzer hadn't made a breaking change with so many ACTIVE OS's. This broke far more than I realized since the cross-compiled binary isn't actually static like I thought it would be. But now my real issue is how do I get a library or file? statically linked in my binary.

It should work if you pass --target=x86_64-unknown-linux-musl to the build command.

Why though?

Why that would work? It will work because it uses musl instead of glibc, which is always statically linked.

1 Like

I see. Is this a requirement of musl, forcing the Rust compiler to statically link against it or is there some other reason?

Well, Rust compiler in general prefers static linking over dynamic, unless explicitly told otherwise. It's just that glibc can't be, AFAIK, linked statically at all, due to its design.

1 Like

I'll try that, but Raspberry Pis are Arm, so I'll have to find a linker for that.

I did have to change the target and download a different toolchain to get a different linker, but musl was the fix!

I am curious about RedDocMD's question though. Why is musl static, but glibc is dynamic?

I don't know.

It's become the convention, basically.

You can statically link with glibc, but you lose some functionality, so it's generally discouraged. There might be some trickiness around licensing too.

You can dynamically link with musl as well, but systems using musl are relatively rare (alpine being the most common example), and you don't really lose anything by statically linking with musl.

Musl may become dynamically linked by default in the future: Update the existing musl targets to be dynamically linked. · Issue #422 · rust-lang/compiler-team · GitHub You can still make it statically linked using RUSTFLAGS="-Ctarget-feature=+crt-static" once the default is flipped. The same option can work for glibc in some cases, but you must make sure that every library is statically linked in. In addition NSS doesn't work anymore as it requires loading dynamic libraries. NSS is used for things like looking up domain names, user information and more. See Name Service Switch (The GNU C Library) for more info. In addition as noted by @rschoon glibc is licensed under LGPL which requires users of your program to be able to replace the LGPL licensed library if I understand correctly. When dynamically linking this is trivial, but when statically linking you would either have to provide the source code of your program or I think all object files and the linker invocation necessary to link it as user against a different glibc version.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.