How does Golang's cross compilation differ from Rust's

For example, if I want to cross compile my Golang program for Windows

GOOS=windows GOARCH=amd64 go build main.go

If I want to cross compile my Rust program, I also need to obtain cross-linker for specific platform which often means compiling gcc.

So how their internal differs so that cross-compiling Rust program needs explicit installation of cross toolchains?


From what I understand, Go uses a backend toolchain that comes from Plan 9, which was already a "native" cross toolchain, so they more or less got it "for free".

Rust, on the other hand, is using LLVM on the backend which is also a "native" cross toolchain... but LLVM doesn't have a production-ready linker. As a result, Rust uses the host platform's linker. Aside from the MSVC toolchain, the platform linker will be the GNU linker ld, which only links for a single target platform. This means you need a cross linker, which sometimes means building the GNU Compiler Collection suite from source. And as for MSVC, that can only target Windows.

So all this means that while Rust can compile for any supported target, it just can't link the results into an actual binary.

Hopefully, LLVM's linker lld will eventually be good enough to replace ld. Then, Rust can just ship lld along with the compiler and avoid this issue. However, even then, you'll probably still need to acquire cross libraries, because in order to link against something, you need the thing you're linking against.