4 ms·
"Static linking and cross-compiling are built-in." I found out that the above is not completely true. According to the official Rust documentation, only Rust d
by manifoldgeo 7y ago
"Static linking and cross-compiling are built-in."
I found out that the above is not completely true. According to the official Rust documentation, only Rust dependencies are statically linked by default. But compiled Rust programs depend on more than Rust dependencies, as they also use shared C libraries. The capability is built-in, but it's definitely not straightforward.
"Pure-Rust dependencies are statically linked by default so you can use created binaries and libraries without installing Rust everywhere. By contrast, native libraries (e.g. libc and libm) are usually dynamically linked..."[1].
I did a small experiment to make a from-scratch Docker container with no dependencies and a single Rust binary and found out that I could not do that without jumping through some hoops[2]. I had to have it include a minimal implementation of libc called "musl". See my write-up here[3]. If anyone has found another way around this I would love to hear about it and make a correction in my write-up.
References:
[1]: https://doc.rust-lang.org/1.13.0/book/advanced-linking.html#static-linking https://doc.rust-lang.org/1.13.0/book/advanced-linking.html#...
[2]: https://doc.rust-lang.org/1.13.0/book/advanced-linking.html#linux https://doc.rust-lang.org/1.13.0/book/advanced-linking.html#...
[3]: https://bxbrenden.github.io https://bxbrenden.github.io
- kouteiheika 7y agoTo be honest you're overcomplicating the whole thing by involving Docker in the build process. Assuming you have Rust installed (which is only one `apt-get` or `curl` + `sh` invocation away) and your project does not depend on any external C libraries (except libc) then building a fully-static Linux executable is as simple as those two commands: rustup target add x86_64-unknown-linux-musl cargo build --release --target=x86_64-unknown-linux-musl There are no hoops to jump through here. I can totally understand using Docker for something which can be a pain to setup a toolchain for or install all of the dependencies for, but for the Rust compiler I see very little reason for running it inside of a container except in a very few very niche cases.
- staticassertion 7y agoAt one point docker was the only way to do this, I think. So if you start searching the internet for how to do static linking with musl you're very likely to find links to the docker'd approach.
- steveklabnik 7y agoI don't think docker has ever been the only way to do this, but it is a popular one. It helps when you go beyond pure Rust.
- staticassertion 7y agoMaybe not the only way, but it was the easiest and most widely recommended way when I was figuring out how to do musl builds around 2 years ago.
- steveklabnik 7y agoHuh, I've just been pointing people to https://blog.rust-lang.org/2015/04/24/Rust-Once-Run-Everywhere.html https://blog.rust-lang.org/2015/04/24/Rust-Once-Run-Everywhe... for the last five years. Maybe someone was recommending Docker a lot and I just missed it.
- staticassertion 7y agoMaybe it's the more niche use case of deploying to AWS Lambda before custom runtimes.
- manifoldgeo 7y agoEdit: I mistook the child comment of my comment as one from steveklabnik. Sorry, was not sarcastically calling you a Rust core developer :-). He really is one, see his profile.
- manifoldgeo 7y agoHey, thank you for the feedback! If I had known about that `rustup target add` command for musl on linux it would have saved me a ton of time. I agree with what you said about docker. I mostly involved docker as an academic experiment. Since I usually write in Python, I've never really had the joys of a statically linked binary with no outside dependencies. Now that I've been playing with rust, I get to finally experience that, and to prove that, I wanted to throw it into a container where it was starved of all other dependencies and see my binary work by itself. As for incorporating the other docker container that imported musl for me and added it to my binary during the build, that was all I could really find to get it done easily (lazily). Now I have your suggestion which is much easier. Anyway, thank you very much! It's cool talking to a Rust core developer.