Hacker News new | ask | show | jobs
by hazz99 1425 days ago
I’m using Bazel to build my rust project (Using the rules_rust rules) and it’a become quite a pain to use in concert with docker.

This is not a complaint about Bazel specifically, its fantastic, and easily my favourite build system bar none.

However it cannot cross compile Rust. This means if I’m developing on my MacBook, and I want to compile a Rust binary and put it in an Ubuntu docker container, I can’t do it on my host machine. I need to copy the source into the container and build it there, using multistage builds.

But this is -extremely slow- because it cannot take advantage of Rusts build caching. I’m talking 10-15 minutes for my small Rust project.

Has anyone run into this? How do you work around it?

I’ve considered running a Bazel remote execution server on a local Ubuntu VM, but this feels like so much extra complexity just to use Rust, Bazel and containers.

6 comments

Bazel can cross-compile Rust, but you need a linker that can produce target executables. Cargo has the same limitation.

Apple ld doesn't support Linux as an output target, so you need to use GNU ld or LLVM lld instead.

Code examples at https://john-millikin.com/notes-on-cross-compiling-rust#baze...

Why not just mount the code in the container instead of copying it over? Rust deals very cleanly with build artefacts from different architectures so there's no risk of corruption.
This is a good idea but there is tension between this straightforward approach and the fact that, on macos, docker is running in a VM so it's inherently slower.
Isn't docker trying to use virtualization from the OS to run linux on "bare metal"? If so it should acheive similar speeds to native linux
The virtualized storage layer could actually be a bottleneck here. Though I think they've improved the performance of it to the point where it might no longer be a bottleneck but I'm not sure.
You might want to try using Docker's cache mounts? https://docs.docker.com/engine/reference/builder/#run---moun...

I've been using them locally of late, and they're excellent for storing state that's not obviously identical across invocations of the same layer.

You can cache the Rust target and make it use Rust's cache properly.

There are two common ways i'm familiar with. Cargo Chef and Manually. Manually can be a bit involved, but you basically just build with empty source and prune your fake-lib files from the cache dir. Cargo Chef is very easy.

My docker images build as fast as my local images. Though if you have many crates in a workspace it can start to become difficult.

I haven't used it yet but https://github.com/nadirizr/dazel might help. It runs bazel inside a docker container via a seamless proxy.
"MacBook, Rust, Bazel and containers." what is the essence of what you are trying to accomplish. focus on that.