I’m doing some experimenting with using rust to build cross-platform graphical apps.
The goal is to have a single codebase from which I can build iOS, Android, Linux, OS X and Windows versions of the app. I’m thinking the easiest path to get there is to lean on SDL2 and the Piston game framework on top of that.
I guessed that iOS would be the more difficult of the two mobile platforms to
get working within the Rust ecosystem since it gets less attention (There’s an
android build as part of the official
CI but no iOS one yet). That said,
iOS’s build system is a lot more sane than Android’s NDK so maybe it won’t be
so bad. Anyhow, I decided to try to get going on iOS first and to my surprise,
I haven’t run in to anything insurmountable just yet, after a day of
experimenting. I’ve gotten as far as building a Piston program for
armv7-apple-ios architecture including linking it against SDL2.framework
(built with github/manifest/sdl-ios-framework).
I still haven’t tried running this on a device yet as I’m pretty sure I’ll need
a host app that handles the UIApplicationMain invocation etc, I plan to
experiment with that next.
What follows is a document of the steps it took me to successfully build (not
run) a Piston program with SDL2 for the
See what breaks
I started by just running
cargo build --target=armv7-apple-ios to see what
breaks. The error I got was:
“Can’t find crate for
std” isn’t the most obvious error but what it means is
the tool chain I had installed (nightly via multirust, in my case) wasn’t built
with the target I requested. Ok so I have to build the rust compiler myself.
Building rustc for cross-compilation
It’s as simple as passing
./configure when compiling rust.
I wanted my version to be pinned to the rustc version I have installed with
multirust so I wrote a script to update my arm version of the compiler.
It’s a bit hacky and I’m not necessarily recommending you do it like this but
I’ll share it anyhow.
The script assumes a directory structure like:
Then I just symlink in a
cargo binary from the system toolchain into the arm
chains bin/ since it doesn’t seem to need to be custom. If you’re using
multirust, don’t symlink $(which cargo) because that’s just a proxy script and it
will break if its location changes, you need to find the actual cargo bin and
symlink it in. For me this was:
Then make the toolchain available to multirust for overriding:
Cargo build again
First, we should override our toolchain to the freshly built one. If you followed the instructions above that
multirust override ios
Now that we have an ios rust toolchain we can give
--target=armv7-apple-ios another shot, this time we make it a bit further and
fail to link. Awesome it’s exactly as I expected:
I didn’t expect it to magically know where SDL.framework is (As I mentioned
earlier I built it from scratch and just have it in my code folder somewhere)
but I have no idea how to get the
-L framework=... flags that
cargo. I was hoping to find something in the crates.io
documentation but didn’t see it. Please do let me know if this is supported
and I’m just missing it. For now I can take the failed
rustc command reported
cargo build --target=... -v and append the framework flags required to
get everything to build and link:
All of those
-L framework= and
-l framework= flags are the ones I needed to
add to satisfy all of the
Undefined symbols for architecture armv7 errors
through trial and error and googling the symbols to determine which iOS
Frameworks each was referring to.
And with that I’ve compiled a binary for
armv7-apple-ios. Next stop, figuring
out how to make a host app bundle to stick it into and actually run it on
I’m really excited to see rust supporting so many architectures right out of the
gate. I’d love to see the cross-compilation toolchain ease-of-use improved.
Better diagnostics for missing toolchains would be great. Rather than just
complaining that the crate
std can’t be found a hint that the requested
toolchain is completely missing would be better. A way to specify the
frameworks to link in my
Cargo.toml would also be really welcome (though
I have a feeling maybe I’m just missing something obvious here).