Android Development in C
This article just describes how to build simple terminal application in C and C++ that finally run on an Android device. GUI development is not addressed.
Prerequisites
Packages required for ARM development in C
Most Android devices are equipped with a APU utilizing ARM architecture. Therefore, binaries for ARM must be created. The following packages must be used on Debian systems to install compilers for C and C++:
- gcc-arm-linux-gnueabi
- g++-arm-linux-gnueabi
The program adb is required for communicating with the Android device. Package: android-tools-adb - Documentation can be found here.
Troubleshooting adb
If "adb devices" returns "???????????? no permissions", the following commands can help:
adb kill-server && adb start-server
This should be executed as root.
Mounting /system read-write
That's required to write binaries to /system/bin so they can be executed. Normally, /sdcard is mounted with noexec option, hence it doesn't qualify for starting binaries from there.
mount -o rw,remount /system
Terminal emulator on Android device
A terminal emulator can be used on the device to start programs.
- Android Terminal Emulator by Jack Palevich in Google Play Store
- Android Terminal Emulator by Jack Palevich in F-Droid Repo
Hello World example in C
helloworld.c
#include <stdio.h> int main(int argc, char** argv) { printf("Hello world!\n"); return 0; }
Building and deploying
arm-linux-gnueabi-gcc -static helloworld.c -o helloworld adb push helloworld /system/bin
Running
Either with adb shell /system/bin/helloworld
or by executing it on the device using a terminal emulator.
Hello World example in C++
helloworldcpp.c++
#include <iostream>
using namespace std;
int main (int argc, char **argv) { cout << "Hello World from C++!" << endl; }
Building and deploying
arm-linux-gnueabi-g++ -static helloworldcpp.c++ -o helloworldcpp adb shell /system/bin/helloworldcpp
Compiling GNU coreutils
Downloading
I am developing on Ubuntu 14.04 which ships with coreutils 8.21. coreutils have a lot of dependencies (like autoconf, autopoint, patch...), so to keep things simple, I grab the sources that match my operating system's version: coreutils_8.21.orig.tar.gz 11.7 MiB Download page
Customizing
After extracting the files from that archive, I do a "./configure" in the directory that contains the files. This process takes about 1 min 45 sec. After that it is important to customize the "Makefile": Search for a line containing
CC = gcc -std=gnu99
and replace it by
CC = arm-linux-gnueabi-gcc -std=gnu99 -static
Why "-static"? Otherwise the programs get linked dynamically, so they depend on the loader to resolve linked libraries. When testing on my Ubuntu machine, it was no problem:
qemu-arm -L /usr/arm-linux-gnueabi/ program
However, on my destination device running Cyanogenmod 9, I always get a "No such file or directory" error when trying to run those files.
Building
After doing a "make" - which runs about 2 min 30 sec - everything works fine. If you want to test if a program was linked statically or dynamically, use the file program:
file program
Example output:
$ file src/sleep src/sleep: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=06a81ace0e2dabd5491dea6923ce0832295ba3f8, not stripped