Building for Android
From Gnash Project Wiki
To start off with, Android only comes with Java based developers tools, so for us C++ projects, you have to go through the pain of getting a development environment setup. So to start, download both the Android SDK, and the Android source tree, both huge. Stick the SDK some place accessible, and then untar the sources. Android builds relatively easy, although as of March 29, 2009, you had to invoke make like this make BUILD_WITHOUT_PV=true, or you get weird errors. This appears not to be a problem a year later in March 2010.
The Android sources come a prebuilt ARM cross compiler in prebuilt/linux-x86/toolchain/, so you'd think we could use that. No such luck, while the C compiler is ok, the C++ compiler is crippled. No iostream support in libstdc++, no locales, etc...Then to make it more fun they use their own libc called Bionic, which is trimmed down for embedded devices. A bit like newlib, but is coupled to the platform much tighter.
The Code Sourcery ARM toolchains work too for C code, and although it has better C++, iostreams won't work as the Code Sourcery versions are built with newlib, and not Bionic, so there are problems. I had gotten dynamic linking working with a custom crt0.S startup file, but static linking worked fine by redefining the entry point.
To compile with the Code Sourcery toolchain, use this example as the command line. This uses the headers that come with Code Sourcery which are from newlib. While this works for C code, for C++, we can't mix /opt/CodeSourcery_G++/bin/arm-none-eabi-gcc -Wl,--entry=main -nostdlib -L/usr/local/android-arm/sysroot/usr/lib -lc -o hello hello.c -lc -lgcc -static
or with the prebuilt tools from Google: /usr/local/src/android/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-gcc -nostdlib -L/usr/local/android-arm/sysroot/usr/lib -lc -o hello hello.c -lc -lgcc -static -I/usr/local/android-arm/sysroot/usr/include -Wl,--entry=main
I've built a traditional style GNU cross toolchain for Android. You can grab a snapshot of this work in progress from here. This has many additional libraries, and full C++ support on Bionic. The current problem is Bionic has pthreads built into libc, so there is no separate libpthread. This confuses Boost to where it won't build with POSIX thread support, which Gnash needs. Boost itself is very picky about compiler versions. Versions of Boost from 1.34.0 to current trigger a G++ bug I've only seen when cross compiling. The bug appears as this message at link time: undefined reference to `__sync_add_and_fetch_4' collect2: ld returned 1 The current workaround for this bug is to only use Boost 1.33.1, which doesn't have this problem. I tried several other versions of G++, but this bug is still in G++ subversion sources, and effects several architectures. (MIPS, SH4, ARM in my experience). I also had to hand hack the Boost config files to force it to build pthread support, plus I had to set BOOST_HAS_GETTIMEOFDAY as well for the data_time library.
If you are using the Code Sourcery toolchain, or my older custom built one, there is also something weird with entry points in the startup code in the older SDK/NDK. I shouldn't have to specify using main, _start is the usual default, but this doesn't exist in the crt0 shipped for Android. So we force the entry point to be main, which is all _start does anyway as we don't have any command line arguments. For C++, this is trickier, as you have to initialize the constructors. Back when I used to hack on cross toolchains at Cygnus, _start called __main() instead, but that appears to have changed, so I'm tracking down what the new style is.
Well, picking this up again after about a year, the new style is called "working correctly". Part of the reason for this is Google released a Native Development Kit for Android, so I no longer have to pull all the pieces out of the SDK, which was tedious. The earlier releases of this NDK were still insufficient to support a C++ toolchain, but the current one has finally caught up. The current NDK is still crippled to not support C++ beyond the minimal WebKit needs, and the prebuilt compiler still has libstdc++ usage disabled completely. We don't care about that, as we build libstdc++ with the new toolchain, which removes this restriction.
I updated to the Android NDK, which had a new release in March 2010, and rebuilt GCC as a cross compiler using svn revno #157396. In the past I had to use the Code Sourcery sources, which being nicely stable, were also out of date. Now Android is handled correctly as a machine target (-mandroid), specifiable on the command line. This is then processed by the GCC specfile, which control options to the various phases of the compilation and linking process to "do the right thing" now.
Getting G++ to build is now pretty easy other than one ugly hack cause I'm lazy. I used this to configure GCC: /home/rob/projects/gnu/gcc/configure --target=arm-linux-eabi --prefix=/usr/local/android-arm --with-sysroot=/opt/android-ndk-r3/build/platforms/android-5/arch-arm --enable-multilib --disable-shared --with-gnu-as --with-gnu-ld --with-ld=/usr/local/android-arm/bin/arm-linux-eabi-ld --with-as=/usr/local/android-arm/bin/arm-linux-eabi-as --disable-libssp --enable-threads --disable-nls --disable-multilib --disable-libmudflap --disable-libgomp --with-arch=armv5te --with-build-time-tools=/usr/local/android-arm/bin --with-pkgversion='Gnash team' --disable-libffi target_alias=arm-linux-eabi --enable-languages=c,c++
The ugly hack is a problem caused by using Bionic instead of newlib. Deep in the configure.ac files for libiberty and libstdc++ is a test that for non-newlib targets, look for dlopen(). This of course fails with any non newlib but cross compiled C library. So you can either go through patching the configure.ac files to not do the AC_LIBTOOL_DLOPEN configure test, and regenerate the configure scripts. The other lazy hack is to just edit the configure scripts for libiberty and libstdc++ to not exit where this test fails, or if you're truly lazy, just replace exit with echo and reconfigure.
Anyway, untar this in /usr/local/, put /usr/local/android-arm/bin in your path, and invoke it as arm-eabi-g++. It's a port of GCC 4.5.0 (from svn). As a C compiler, this toolchain works great, and it's much easier to build Android executables than the other tools as it's all integrated. For C++. it does fully compile everything, but there seems to be a problem with boost. Boost is the biggest pain in the #$%^@# to cross compile successfully for a non-standard target, so I haven't gotten it rebuilt with the new toolchain I just built.
adb
adb is the remote console for the Android. Once you succeed in getting your application compiled, you use "adb push executable /data", where /data can be anywhere on the phone's filesystem. Then to run your program use adb again "adb shell /data/executable". Just running "adb shell" gives you an interactive shell on the phone.

