Cross Compiling ELF Executables for Android
Android devices primarily use ARM processors, and applications are packaged as APKs which contain Dalvik or ART bytecode. However, there are situations where you might need to run ELF executables on an Android device. These executables can be compiled from C, C++, or other languages.
This guide covers the process of cross-compiling ELF executables for Android.
Understanding Cross Compilation
Cross compilation refers to compiling an executable for a target platform that differs from the host platform where the compiler runs. In our case, we want to compile an executable for an ARM Android device while using a development machine that likely runs on x86 or x64 architecture.
Steps for Cross Compilation
1. Toolchain Setup
- Android NDK: The Android NDK provides the necessary tools and libraries to build native code for Android. Download and install it from https://developer.android.com/ndk.
- Cross Compiler: The NDK includes a cross compiler tailored for ARM architecture. You can access it using the
arm-linux-androideabi-
prefix for tools like the compiler (gcc
) and linker (ld
). - Environment Setup: Set up environment variables to point to the NDK directory and the toolchain. For example, on Linux:
export NDK_HOME=/path/to/android-ndk export PATH=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
2. Building the Executable
- Source Code: Create your C/C++ source code (e.g.,
myprogram.c
). - Compile Command: Use the cross compiler with the
arm-linux-androideabi-
prefix to compile your code. Example:arm-linux-androideabi-gcc -o myprogram myprogram.c
- Linking Libraries: If your program depends on external libraries, include them in the link command. You can find appropriate libraries within the NDK or use static libraries.
arm-linux-androideabi-gcc -o myprogram myprogram.c -L/path/to/libraries -lmylibrary
3. Creating the Executable for Android
- Executable File: You’ll get an executable file like
myprogram
. This file is designed for ARM architecture but might not be directly executable on an Android device. - Copying to Device: Use ADB (Android Debug Bridge) to transfer the executable file to your Android device:
adb push myprogram /data/local/tmp
- Making Executable: On the Android device, make the file executable using shell commands:
adb shell cd /data/local/tmp chmod +x myprogram
4. Running the Executable
You can execute the file directly on the Android device using:
./myprogram
Example: A Simple “Hello World” Program
// hello.c #includeint main() { printf("Hello World!\n"); return 0; }
arm-linux-androideabi-gcc -o hello hello.c adb push hello /data/local/tmp adb shell cd /data/local/tmp chmod +x hello ./hello
Hello World!
Table: Common Toolchains
Android NDK Version | Toolchain |
---|---|
r17b | arm-linux-androideabi-4.9 |
r21d | arm-linux-androideabi-4.9 |
r24 | clang-9 |
The NDK offers a variety of toolchains based on different compiler versions and architectures. The recommended practice is to consult the documentation for the latest NDK version you’re using to determine the available toolchains.
Challenges and Considerations
- Target Platform: Android devices have a diverse range of processors and architectures (ARM, x86, etc.). Ensure your cross-compiler is compatible with your device’s architecture.
- Libraries: If your program relies on external libraries, you need to ensure that these libraries are available on your target Android device. The NDK provides some basic libraries, but you might need to cross-compile or find Android-specific versions of necessary libraries.
- Debugging: Debugging cross-compiled code can be more complex. Tools like GDB (GNU Debugger) can be configured to work with Android, but they require additional setup.
Conclusion
Cross-compiling ELF executables for Android enables running native applications on Android devices. While it involves understanding toolchain configurations and ensuring compatibility, it offers flexibility for scenarios where Android’s standard development environment doesn’t suffice.