Cross compiling aarch64-linux-android on macOS

Hi - I'm rather new to rust and have become stranded in a cross compilation swamp of despair. I'm trying to compile this project for android, on my mac ( have tried both an M1 and an intel based macbook pro). It cross-compiles fine on a linux laptop, but I'm struggling to get the mac working. Has anyone seen this before?

   Compiling openssl v0.10.38
thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value', compiler/rustc_codegen_llvm/src/back/archive.rs:361:67
stack backtrace:

It's a fairly standard install - have installed the ndk-bundle using sdkmanager ndk-bundle and set the NDK_HOME env var to the install directory for the bundle.. but nothing much else.

Feels like it will just be a configuration or env var missing.. but I'm unsure where to even look!

It looks like a compiler bug, possibly caused by invalid inputs. That unwrap is most likely from file_name().unwrap(), so the compiler ended up using a path without a file name (/) for some resource.

As for cross-compilation, I expect it's going to be painful on macOS, because macOS doesn't have a standard location for "sysroots" of other operating systems. On Linux the pkg_config crate has some auto-detection of cross compilation, but there's no such thing on macOS.

So on macOS you will have to ensure that pkg-config finds openssl for android, and NOT for macOS. It's not enough to configure NDK for its own use. You need to configure everything for every Cargo sys crate to make it look for android libraries and not look at macOS libraries, and it's specific on crate-by-crate basis, and there's no standard for this.

Thanks for the quick reply!
Yes - I think the issue when unwrapping is just due to being unable to locate openssl - though I have openssl installed (via homebrew) and the env var for OPENSSL_DIR set. The openssl crate does say that it will likely auto detect an installation via homebrew.. but there may be something awry with my configuration.

And yes, I'm starting to think that I'll just have to use a VM, either hosted or run locally, in order to cross compile the android build. Not the end of the world. :man_shrugging:

You can't use Homebrew for this, because Homebrew gives you macOS-only versions of libraries, and they're not compatible with Android. If the build happens to find them, it will break cross-compilation.

Cross-compilation requires you to have proper Linux/Android libraries installed on macOS, and on macOS there's no tool for that.

If NDK comes with OpenSSL and an appropriate .pc file for it, then you may need to tweak PKG_CONFIG_SYSROOT_DIR to point it there, or set OPENSSL_LIB_DIR and OPENSSL_INCLUDE_DIR to location of pre-built Android version of OpenSSL (not the macOS/Homebrew one!)

Alternatively, you can try setting vendored feature of OpenSSL by adding this to Cargo.toml of any crate you build:

[dependencies]
openssl = { version = "0.10", features = ["vendored"] }

yes, true. I did also download openssl libs for android and used AARCH64_LINUX_ANDROID_OPENSSL_DIR to specify that version of the libraries as well. Doesn't help with the initial issue, so that is likely something else after all.

I've reverted to using ubuntu rather than macOS and that's working nicely - cross compiles to aarch64 fine.

As an aside, if anyone else has issues - I did try using parallels on the M1 macbook, but there isn't an android sdk for that architecture yet. I've instead gone back to an older, intel based macbook for compilation. Once again, running ubuntu via parallels. A little clumsier than I'd like, but fine.

Thanks again for your help!

On M1 it's possible to use Docker which runs aarch64-linux, and from there you can cross-compile to other architectures more easily than on macOS directly. I use this approach for building x86-64 Linux executables, but I haven't tried Android.

Yes, I think that's probably best. Have marked as the solution to help any other lost souls who stumble on this.

My colleague tried docker and ran into troubles, so I didn't try it myself. At this stage, given the lack of android sdk support, some sort of virtualisation is I think the only way to cross compile the android build reliably.