Cross compiling for Android from Windows using clang fails with "could not exec the linker, %1 is not a valid win32 application"


#1

Hello everyone,

I’m trying to get started with Rust on Android. The first step is just a simple hello world application that should be copied over and executed via adb as outlined here.

I’m closely following this Mozilla blog post, and have installed NDK 16b, created a standalone toolchain for arm in the project path and copied the target config to ~/.cargo/config.

However, when building the application with cargo build --target armv7-linux-androideabi I get an error that says:

error: could not exec the linker `C:/Users/waved/Desktop/devel/projects/hello_android/NDK/arm/bin/arm-linux-androideabi-clang`
  |
  = note: %1 is not a valid Win32 application. (os error 193)

which is misleading because it IS a valid Win32 application, I can run it just fine from the command line.

Halfway through writing this I realized I could test to use gcc instead of clang to invoke the linker. It worked, but I can’t test the executable at the moment because my phone isn’t rooted.

Does anyone know why this error happens?


#2

May be mix of 32bit and 64bit? Some exe/dll are 64bit and some 32bit?

You don’t need root to execute,
look for example in my project rust_swig: https://github.com/Dushistov/rust_swig/blob/master/android-example/run-on-adroid.sh

this script helps to use cargo test --target=arm... for execute unit tests on android devices, and it works just fine for not rooted devices.


#3

That’s usually not an issue, unless a 64-bit process tries to load 32-bit DLLs, which most likely means the software distribution itself is broken. 32-bit apps are still pretty common on Windows.

Thanks, I’ll take a look at this.
For some reason this fails to copy.
Apparently the Windows version of adb doesn’t work with git bash, it gets the paths mixed up for some reason. Manually copying to device via PowerShell, however, revealed the binary is working. I might port your script to .bat or PowerShell so I can use it. Thanks!

The problem was that arm-linux-androideabi-gcc is an exe and arm-linux-androideabi-clang is a bash script; if I specify arm-linux-androideabi-gcc.cmd (which is the Windows batch equivalent) it seems to compile/link just fine.

However, this brings me to another question:
If I want to enable building from Windows as well as from Linux, I’d need to set cargo’s linker property to the build platform-specific script that invokes clang. Is there a property for doing that depending on the build host OS?