Compiling imgui-rs and other C++ based crates for Android


#1

I am trying to get the imgui-rs crate to work within an Android application but I’ve got a problem with the way it uses g++ instead of gcc to compile the cpp files.

My .cargo/config file includes the following definitions:

[target.armv7-linux-androideabi]
linker = "/Users/tanis/Documents/android-ndk-arm/bin/arm-linux-androideabi-gcc"

[target.aarch64-linux-android]
linker = "/Users/tanis/Documents/android-ndk-arm64/bin/aarch64-linux-android-gcc"

[target.i686-linux-android]
linker = "/Users/tanis/Documents/android-ndk-x86/bin/i686-linux-android-gcc"

but it looks like it can’t find gcc or g++ (it uses gcc for stb_image and g++ for imgui)
The error is the followint:

error: failed to run custom build command for `imgui-sys v0.0.15`
process didn't exit successfully: `/Users/tanis/Documents/minigame-rust/target/debug/build/imgui-sys-699678620b97622a/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("armv7-linux-androideabi")
OPT_LEVEL = Some("0")
TARGET = Some("armv7-linux-androideabi")
HOST = Some("x86_64-apple-darwin")
TARGET = Some("armv7-linux-androideabi")
TARGET = Some("armv7-linux-androideabi")
HOST = Some("x86_64-apple-darwin")
CXX_armv7-linux-androideabi = None
CXX_armv7_linux_androideabi = None
TARGET_CXX = None
CXX = None
TARGET = Some("armv7-linux-androideabi")
HOST = Some("x86_64-apple-darwin")
CXXFLAGS_armv7-linux-androideabi = None
CXXFLAGS_armv7_linux_androideabi = None
TARGET_CXXFLAGS = None
CXXFLAGS = None
PROFILE = Some("debug")
running: "arm-linux-androideabi-g++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-march=armv7-a" "-march=armv7-a" "-mfpu=vfpv3-d16" "-mfloat-abi=softfp" "-o" "/Users/tanis/Documents/minigame-rust/target/armv7-linux-androideabi/debug/build/imgui-sys-baa2353af33cf674/out/third-party/cimgui/cimgui/cimgui.o" "-c" "third-party/cimgui/cimgui/cimgui.cpp"


failed to execute command: No such file or directory (os error 2)
Is `arm-linux-androideabi-g++` not installed?



--- stderr
thread 'main' panicked at 'explicit panic', /Users/tanis/.cargo/registry/src/github.com-1ecc6299db9ec823/gcc-0.3.51/src/lib.rs:1239:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Is there any way to tell cargo where the C/C++ compiler/linker lives? The way I used seems not to work at all.


#2

Your linker configuration is correct, but the linker is not used for compiling C code.

These crates both use the gcc crate in their build scripts. This crate knows about the names of the Android NDK’s compilers, and should work out of the box if you add the appropriate toolchain bin directory to your $PATH.

Or you can use environment variables like $CC_armv7-linux-androideabi and $CXX_armv7_linux_androideabi to explicitly tell it where to find the C and C++ compilers.


#3

Right now I’m using the following command line and it works but it’s definitely ugly :slight_smile:

CC=/Users/tanis/Documents/android-ndk-arm/bin/arm-linux-androideabi-gcc CXX=/Users/tanis/Documents/android-ndk-arm/bin/arm-linux-androideabi-g++ AR=/Users/tanis/Documents/android-ndk-arm/bin/arm-linux-androideabi-ar cargo build --no-default-features --target armv7-linux-androideabi --lib

would the gcc crate honor those environment settings for dependencies if I set them from my build.rs script?


#4

Dependencies are built before your own build script runs, so unfortunately it is not able to modify their build scripts’ environments.

The simplest fix might be to add the "android-ndk-arm/bin" directory (along with any other toolchains you need) to your PATH, in your .profile or other shell config file. The tools in these toolchains are all prefixed with their targets, so it should be okay to have all of them in your PATH at once.


#5

And I suppose there’s no other mechanism builtin in Cargo that is being run before dependencies are built. That would have made things much tidier. Are there any plans for such a feature, along with some sort of post build script?