[Android Software/Hacking General [Developers Only]] JustArchi:
[SIZE="+1"]What is a Cross-Compiler?[/SIZE]

[SIZE="+1"]How is that connected with an Android?[/SIZE]

In order to create a native C/C++ binary for an Android, you must firstly compile the source code. Usually you can't do so on an Android itself due to lack of proper tools and environment, or hardware barriers, especially amount of RAM. This is why you should learn how to cross-compile, to create a binary on your PC, that your ARM-based Android will understand.

[SIZE="+1"]Why do I need it?[/SIZE]

You need to learn cross-compiling technique if you want to run native C/C++ programs on an Android. Actually, if you've already built your own custom ROM from AOSP sources (i.e. CyanogenMod), then you used cross-compiling tools and methods even without noticing :).

Building an AOSP ROM is fairly easy, there's one command like brunch, which does the job. However, what if you want to compile a custom, not natively included binary? This is the purpose of this tutorial.

[SIZE="+1"]What I will learn from this guide?[/SIZE]

How to properly set C/C++ building environment

How to build a native C/C++ application for Android device

How to optimize native binaries for my device

[SIZE="+1"]Step 1 - The Beginning[/SIZE]

You should start from installing any Linux-based OS, I highly suggest trying a Debian-based distro (such as Ubuntu), or even Debian itself, as this tutorial is based on it :).

In general, I highly suggest to compile an AOSP ROM (such as CyanogenMod) for your device firstly. This will help you to get familiar with cross-compiling on Android. I also suggest to compile one or two programs from source for your Linux, but if you're brave enough to learn cross-compiling without doing any of these, you can skip those suggestions :).

[SIZE="+1"]Step 2 - Setting up[/SIZE]

Firstly you should make sure that you have all required compile tools already.

This should do the trick and install all required components.

I suggest creating a new folder and navigating to it, just to avoid a mess, but you can organize everything as you wish.

Start from downloading NDK from here.

Now you should make a standalone toolchain, navigate to root of your ndk (this is important) and then build your toolchain:

You should edit bolded variables to your preferences. Toolchain is the version of GCC you want to use, 4.8 is currently the newest one, in the future it may be 4.9 and so on. Platform is a target API for your programs, this is important only for android-specific commands, such as logging to logcat. When compiling a native Linux program, this won't matter (but it's a good idea to set it properly, just in case). Install dir specifies destination of your toolchain, make sure that it's other than ndk (as you can see I have ndk in /root/ndk and toolchain in /root/ndkTC).

Now you need to download my exclusive cc.sh script from here and make it executable.

This script is a very handy tool written by me to make your life easier while cross-compiling. Before running it make sure to edit "BASIC" options, especially NDK paths. Apart from that it's a good idea to take a look at DEVICEFLAGS and setting them properly for your device, or clearing for generic build. You don't need to touch other ones unless you want/need them.

Just for a reference, I'll include currently editable options:

As you can notice, my magic script already contains bunch of optimizations, especially device-based optimizations, which are the most important. Now it's the time to run our script, but in current shell and not a new one.

Command "source cc.sh" executes cc.sh and "shares" the environment, which means that any exports will be exported to our current shell, and this is what we want. It acts the same as AOSP's ". build/envsetup.sh", so you can also use . instead of source.

As you can see above, my script should let you know if it properly set everything, especially if $CC points to our ndkTC. It also set a generic "$CCC" and "$CCXX" commands, which are optimized versions of standard $CC. $CC points to our cross-compiler, $CCC points to our cross-compiler and also includes our optimization flags.

[SIZE="+1"]Step 3 - Cross-Compiling[/SIZE]

Now we'll compile our first program for Android!

Create a new file hello.c, and put inside:

#include <stdio.h>
int main (void)
{
puts ("Hello World!");
return 0;
}

Now you compile and strip it:

Remember that $CCC and $SSTRIP command will only work if you source'd cc.sh script explained above. $CCC command compiles source code to a binary with already optimized flags (device flags, optimization level, optimization flags, linker flags), while $SSTRIP command strips "bloat" from output binary, such as comments and notices. The purpose is to make a binary smaller and faster.

You can check if your binary has been compiled properly through readelf command.

As you can see, I've compiled a binary optimized for ARM v7, with THUMB-2 instructions and NEON support. How nice! Is it because of device-specific flags? Let's check what happens if we use $CC instead of $CCC:

As you can see, if you do not specify flags, you'll lose major portion of optimizations. Of course binary will work properly, hence it has been cross-compiled for ARM, but we can always make it smaller and faster! :)

[SIZE="+1"]Step 4 - Testing[/SIZE]

A favourite part of everything, tests! :)

In above example I pushed my binary straight to /system/bin directory, which is in the Android's PATH. If you don't have rooted device that's not a problem, you can use /data/local directory or /storage/sdcard0. You can also upload your binary anywhere you want and download it as any other file, then run from /storage/sdcard0/Download, this way doesn't require even working ADB :). Just don't forget about setting proper permissions afterwards!

Now let's try to run it! :)

If your binary is not in the PATH, you should write full path to your binary of course. As I pushed my binary to /system/bin, I don't need to do so.

If everything finished successfully and you got your very first Hello World response as above, congratulations. You've just compiled and ran your first native C/C++ program on Android device.

[SIZE="+1"]What to do next?[/SIZE]

In theory, you can now compile anything you want. Here are some apps that I'm using in my ArchiDroid ROM:

Pixelserv

Haveged

Dnsmasq

DNRD

Rinetd

These are only a few examples. You can compile anything you want, or even write your own native applications. Good luck!