Search code examples
linuxamazon-web-servicesrustrust-cargo

Cargo build for Linux compilation errors from Once_cell?


I have a cargo workspace project which I build and run on my Windows laptop. The program hosts a backend server. Now, I would like to host this on an AWS EC2 instance which is a Linux machine. What I thought I'd do is first cargo build for linux and then simply put the .exe into the ec2 instance and run it from there.

I tried two things (form my Windows machine):

i) cargo build --target=x86_64-unknown-linux-gnu - this gives me some really strange compile errors , like error[E0412]: cannot find type `Result` in this scope; error: could not compile `once_cell` due to 223 previous errors

ii) Tried another target: cargo build --target=aarch64-unknown-linux-gnu And got pretty much same thing.

Is this some limitiation of once_cell? Or, much more likely, I am missing something fundamental here?


Solution

  • The error you're getting indicates that the standard library can't be found. When cross-compiling from Windows to Linux, it's best to use *-musl targets, to avoid having to come up with the Linux-specific libraries that *-gnu targets require. To fix the errors simply run the following command:

    rustup target add x86_64-unknown-linux-musl
    

    This will install the relevant stdlib. You will have to do this for each toolchain you intend to cross-compile from (if you want to use both stable and nightly or something).

    If you cargo build at this point, and instead of getting a bunch of compiler errors, you should be getting linker errors instead. To fix this, add the following lines to your .cargo/config.toml file:

    [target.x86_64-unknown-linux-musl]
    linker = "rust-lld"
    

    That should be enough to get things built, although some crates may have platform/toolchain requirements that might take some more effort to satisfy.

    Of course, that assumes amazon's ec2 instances are actually x86_64 machines, which they may not be. Similar steps should work for other platforms, just using the required target. For example, to build for a 64-bit arm platform you would just use the same steps but with the target aarch64-unknown-linux-musl, and I use these steps with armv7-unknown-linux-musleabihf to build stuff for my raspberry pi.