Cross-compile to multiple targets from 1 host. A possible focus for 2018?


#1

I’ve been running into an interesting situation for the last year or so: When you want to build and deploy Rust code to multiple targets (in the rustup sense of the word) you quickly find out that it is next to impossible at the moment to just use 1 host and build for Linux, OS X, and Windows, at least when the host is OS X or Linux. I haven’t checked Windows. In practice it is immensely easier to “just find a suitable build host”, which has its own problems e.g. dependency on 3rd parties, and solutions like TravisCI are extremely slow (compared to a regular Rust build, that is).

Xargo seems to help somewhat with this issue apparently. But what I’ve been bumping into this issue repeatedly and I think the ideal workflow would be something like: 1. install the target you want to build for, and 2. use cargo build --target <TARGET> or something like that to successfully build the code.

It’ll probably be tricky to get this done, but the value would be immense.

I’m interested in what you all think about this, do you consider this a useful feature?
And what are the hurdles (technological or otherwise) to take in order to get this feature?


#2

From what I recall last time I looked into this there are 2 main hurdles:

  1. Linker support, I was not able to find a cross linker from macOS to Linux, presumably all the other directions are likely to be missing as well.
  2. C dependencies, cross compilation of C libraries makes build scripts much more complicated. Some support it but I remember having issues with some less used libraries.

As a test I just tried to compile cargo-lichking from x86_64-unknown-linux-gnu to x86_64-apple-darwin, it all went relatively smoothly until the linking stage

(click to expand log)
→ cargo build --target x86_64-apple-darwin
   Compiling unicode-width v0.1.4
error[E0463]: can't find crate for `core`
  |
  = note: the `x86_64-apple-darwin` target may not be installed

error: aborting due to previous error

→ rustup target add x86_64-apple-darwin
info: downloading component 'rust-std' for 'x86_64-apple-darwin'
 53.8 MiB /  53.8 MiB (100 %)   4.1 MiB/s ETA:   0 s
info: installing component 'rust-std' for 'x86_64-apple-darwin'

→ cargo build --target x86_64-apple-darwin
   Compiling strsim v0.6.0
   ...
   Compiling openssl-sys v0.9.11
error: failed to run custom build command for `openssl-sys v0.9.11`
process didn't exit successfully: `/home/wim/sources/cargo-lichking/target/debug/build/openssl-sys-517e656f9804421b/build-script-build` (exit code: 101)
--- stdout
run pkg_config fail: "Cross compilation detected. Use PKG_CONFIG_ALLOW_CROSS=1 to override"
...

→ PKG_CONFIG_ALLOW_CROSS=1 cargo build --target x86_64-apple-darwin
   Compiling num-traits v0.1.37
   ...

error: linking with `cc` failed: exit code: 1
  = note: cc: error: Security: No such file or directory
          cc: error: CoreFoundation: No such file or directory
          cc: error: unrecognized command line option ‘-framework’

From this we can see that rustc is able to compile all the rust dependencies successfully (presumably at least); the openssl-sys build script has some explicit support for cross compilation; and it’s just failing due to not having a linker that supports x86_64-apple-darwin.


#3

Would LLD help with this at all? I know in the past it wasn’t quite ready for prime-time but maybe it’s closer to being ready now. Then possibility Rust could use LLVM for a cross platform backend and linker?


#4

From what I can read from the site it looks like it’s still a WIP on at least WASM, and likely MacOS too.

But perhaps the site is out of date?