Android + HXCPP – a Quickstart Guide

After having some success with making an Xcode template, I thought it would be relatively easy make something similar for eclipse and Android. However, there was nothing but pain for me when I tried, so instead I’ve decided to write this guide.

Prerequisites

There are quite a few prerequisites you need to organize before you can get things going. Android allows building from Windows, Mac and Linux. The procedures are quite similar, except that Windows requires some messing about with Cygwin binaries. The method described here avoids most of the Cygwin pain \- and the google make sytem pain \- by avoiding the google make sysem altogether.

  • Download and install the Android SDK. This is the Java tools and libraries required for building and debugging byte-code applications.
  • Download and install eclipse IDE. This is the IDE that runs the SDK – follow the instructions on the Android SDK page and install the Android plugins too.
  • Install the USB drivers for your device (if required). For my device (HTC Legend) I found the drivers on the phone itself by using it as a thumb drive.

You should now be in a position to build some sample (byte-code) applications for your device.

  • Download the Android Native Development Kit. This allows you to build binary code for your device. Now for HXCPP, it is very important to download the latest build provided at Crystax.net, which is a build done by a generous community member that corrects some of the glaring omissions of the official build, namely RTTI and exceptions. If it is all the same to you, extract it to c:/tools/android-ndk for Windows, and ~/tools/android-ndk for other systems, and this will make the remaining instructions easier.
  • Currenly on Windows, you need the svn version of HXCPP (slightly newer that 2.06.1) which has some include path fixes. See the instructions at http://code.google.com/p/hxcpp/ for getting the latest version.
  • Also on windows, you need the Cygwin dlls in your path. One way to do this is to install the whole Cygwin toolchain and put it in your path. The other way so to drop the two dlls from cygwin-extra.tgz into the ndk binary directory, ie c:/tools/android-ndk/build/prebuilt/windows/arm-eabi-4.4.0/bin.

Project structure

An android project consists several components that all work together.

  • Java Code. The Java code provided in the sample project comes from a couple of places. Because the project is graphics based, the copy NME Java code is included. If the version of NME increases, it may be desirable to update the NME code, either by copying the new code in, or instead linking to the NME code directly. Also, the HXCPP bootstrap Java code is included along with a small Activity wrapper file.
  • Native code. The shared object files provide native code for running on the device. These include the standard libraries, the NME library and the haxe code compiled with hxcpp.
  • AndroidManifest.xml. This controls how your application is deployed, and quite a few things can be done with this file. It is best to consult the Android documentation about what can be done here.
  • Resources & Assets. These can be useful if you want to add standard menus or other GUI elements to your application.

The basic workflow starts by making a change to your haxe source files. You then compile the haxe code to Android cpp, which is in turn is compiled to an android shared object. This .so file is then copied to the libs/armeabi directory in the project. Because eclipse does not recognize a change to the shared objects as a important update, it is then necessary to touch one of the Java files so that eclipse rebuilds the project. These steps are handled by the build_haxe batch/shell scripts provided with the project, so all you should have to do is change the code and run the script. Then, press the “play” button in eclipse(the first time you do this, you may need to specify Run-As Android Project) and your application should launch.

The haxe code included in the sample directory uses a fixed class name, AndroidMain, as the bootstrap point for building the haxe shared object, libAndroidMain.so. By fixing these names, the build script is simplified. I encourage you to put your main code for the application outside the provided project directory, and edit the AndroidMain.hx and build.hxml files to point to this external application code. This will help with cross-platform development, and keep the boiler-plate code separate from your precious source code.

Creating a New Project

I could not find a very nice way to make a project template, so this is what I’ve come up with. First, download and extract the example project, android-2.06.1.tgz. You may like to rename the parent directory from android-2.06 to something more meaningful at this stage.

At this point, you should be able to build the sample haxe code using the build-scripts provided. This requires your prerequisite installations to be good, so it is worth testing. If you have downloaded the android-ndk to a different location, you can edit the appropriate build script to reflect this. You will need the latest NME code from haxelib. Windows users may also need the svn version of HXCPP.

So that all worked? Congratulations, your system is set up for development.

Next, fire up eclipse, and create a “File – New Project..”, then select “Android Project”, then select “Create project from existing source”, and browse to your newly created directory. You will notice that down the bottom of the Dialog, the properties are filled out with names from the sample project – we will change these next. Once you select “Finish”, your project should be created, and ready to run on your device.

The project and package names are tied into Java and Android naming conventions, as well as the Android manifest, and can be difficult to budge. It is easiest to use the eclipse Refactor-Rename menu option to change the name from “MyActivity” to something more appropriate for you, say “CircleDisplay”. Then in the source tree under “src”, there is a file in com.company called “MyActivity.Java”. Select this, and use the menu option to change its name to “CircleDisplay” too. Similarly, select the “com.company” and change this to something else, in my case “com.gamehaxe” (select preview and agree to everything). There is one final change required – the refactor option misses a reference in the AndroidManifest.xml because it starts with a period. Double click this and in the “AndroidManifest.xml” tab, change the “.MyActivity” to “.CircleDisplay”.

It is important to rename these items because it effects how your application is ultimately stored in the device.

So now you should be good to go – press the play button and select “Android Project”.

There are quite a few things that can go wrong with so many things to install, so I’ve got my fingers crossed for you.

Minor Updates

I have just released a few minor updates to nme + hxcpp, which you can find on haxelib. These are relatively small \- just pushing out a few fixes for some bugs that have been reported. In most cases the bug reports we accompanied by a fix \- you’ve gotta love open source. The iPhone/Xcode template has also been updated, you may need to follow the instructions in the post below.

There is one significant change though – the “nekoapi.dll” file that is used for compatibility between hxcpp binaries (ie, NME) and neko has changed its extension to “ndll” so that neko can communicate directly with it. This allows the String instances created externally to be “blessed” as haxe strings without having to call nekoToHaxe on them, and therefore methods such as substr will work.

The other change of note is that I removed the libfreetype code from the iPhone target, and used native font rendering instead. Let me know if this breaks anything. One side effect is that the default font will now be system dependent, with the iPhone getting its usual font. I will also have to have a good look at the font render quality – freetype may have a little bit better sub-pixel sharpness.

There was a bug in the 2.06 haxe distribution when writing files. I have fixed this by putting an override in hxcpp, which you can access with the command line options: “-lib hxcpp”. I have also folded this change into haxe svn, so you will not need to do this in 2.07.