Cross compiling support

Every time I come back to Rust it seems I waste a bunch of time fighting cross-compilation or the lack of support of it.

One funny example is me yesterday using ansible to build an Axum app and shift it into an Orbstack Ubuntu VM. Turns out that if you build the app on macOS, it'll happily run and then complain that it can't get environment variables.

(Insert 2 hours late at night of me locking myself out of the VM using ansible and then trying to debug systemd EnvironmentFile.)

Can there be some kind of error here saying: "oy, I'm not supposed to be here"?

Supposedly " rustc is a cross-compiler by default" but I've wasted tons of hours already in the past trying to get my macOS machine to build something that will work on Linux (either aarch64 or x86_64) without any success. That's why I'm not going to even try this now.

Isn't it the case that doing something like this is trivial in Go and Zig?

1 Like

Using Go, it is only trivial if you do not interact with the C standard library which Rust does by default as parts of std are implemented using libc. Going through the C library for system calls and the C compiler for linking is the traditional way to do it on Unix-like systems and this need for a full Unix cross toolchain is usually where all the friction comes from. Note that people do work on Rust platforms which remove this dependency, c.f. RFC #2610 and rustix and its linux_raw target which is similar to what Go does when Cgo is not involved.

Zig is easier on the happy path because it basically includes multiple full Unix toolchains. Personally, I am not sure how sustainable it is to include this in the language toolchain itself and it still fails for really exotic (i.e. today mostly embedded) platforms. In any case, you can leverage that work for Rust using cargo-zigbuild.

2 Likes

I feel you. In my experience the greatest pain of cross-compilation in Rust is cross-compiling linked C code. This gave me headaches in the past as well, especially because the respective error messages are mostly unhelpful (since they don't come from rustc).
Having the necessary C toolchain installed and configured via .cargo/config.toml usually fixes those issues for me.

1 Like

I think your best bet is using one of these two third party projects that streamline the process:

I don't know if they work on MacOS, but they do work on Linux to cross compile to other Linux architectures or to e.g. FreeBSD.

1 Like

I can try these approaches again (briefly). I see I was already subscribed to the #2610 issue probably from last time round.

I think the error I got initially was dependent on something to do with OpenSSL which is its own hell.

I get the technical reasons for this, but the result of this is that it is much more likely for people to develop web services in not-Rust if there is this much friction in the development experience. Building a binary in Go on your Macbook and jacking it onto a server definitely is an important use case.

1 Like

See also: Why is "--target" next to impossible to use right? - #4 by kornel

1 Like

Given that the language is feature complete, maybe it would be possible to fix these kinds of things now?

This also dies pretty quickly on openssl.

1 Like

Did you enable the vendored feature of the openssl crate? If not it expects to find a precompiled libopenssl.so in the compiler sysroot, which zig doesn't provide.

2 Likes

I'm sure it's possible to get it work but I did another deployment with Docker containers and then it's easier to just build the Rust app in the Linux container and not to bother with any of this.