Cross-compiling with Android

Step 0: Download the Android NDK

Download the Android NDK. Then the ANDROID_NDK_HOME env to the dir that you unzipped the NDK.

Step 1: Create Android Toolchain

Read about how to create the Android Standalong Toolchain. You will likely create the toolchain with a command like this:

$ANDROID_NDK_HOME/build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-19 
--install-dir=/tmp/my-android-toolchain

Step 2: Create a Meson cross build file

A Meson cross build file tells the Meson build system details about the nature of the cross compile job you will be performing. My cross compile file looks like this:

android_cross.txt

name = 'android'
c = '/tmp/my-android/arm-linux-androideabi/bin/gcc'
cpp = '/tmp/my-android/arm-linux-androideabi/bin/g++'
ar = '/tmp/my-android/arm-linux-androideabi/bin/ar'
ld = '/tmp/my-android/arm-linux-androideabi/bin/ld'
strip = '/tmp/my-android/arm-linux-androideabi/bin/strip'

root = '/tmp/my-android/'

Note: the /tmp/my-android/ prefix is where I installed the Android toolchain

Step 3: Invoke Meson

mkdir android-arm-build
meson android-arm-build --cross-file android_cross.txt

Step 4: Compile

cd android-arm-build
ninja

Multi-class Classification Metric

I am working on a statistical classification project and was looking for a metric that would describe performance of my algorithm. In my case, using accuracy as a metric would not be very useful, because my data sets have very different sizes of classes. For example, I might have a data set made of 95% of class A and 5% of class B. If my model never predicted class B, I might falsely assume that my algorithm was working great because it was predicting the correct answer 95% of the time.

I have read about the F1 Score which seems to be often used as a replacement for accuracy in binary classification problems. To adapt the F1 score to my multi-class problem, I take the average F1 score for each class of data. This seems to work nicely. Here is an example:

String[] truth = new String[]     {"C", "A", "C", "C", "A", "B"};
String[] predicted = new String[] {"A", "A", "C", "C", "A", "C"};

F1 = 0.606061
Acc = 0.666667

B predected as C 1 times
C predected as A 1 times

I have implemented an Evaluation class that can be used by feeding it pairs of true outcomes and predicted outcomes and it will calculate the confusion matrix and F1 score.

Stopping on breakpoint can cause X window system to freeze

I was experiencing this problem when debugging a Java Swing app on my Ubuntu system. When by debugger hit a breakpoint, sometimes the whole X window system would freeze. My only option was to drop to the console (ctrl-alt-f1) and kill the java process. This fix seems to have fixed it:

Add the java VM options:

-Dsun.awt.disablegrab=true

for more details see this

Java Application Installers

I have a Java Swing app that I am preparing for general release and have been looking for a package and install solution. Specifically, I am looking for:

  • Package my jar file into a installer exe that will create a shortcut on the desktop
  • Installation of Java if needed or even better installer package comes with embedded JRE so no separate Java install is needed
  • Cross-platform installer would be nice but Windows users are first priority
  • Low/No Cost

There are several options out there, but my favorite so far is Packr. Packr is an open-source java packager developed by the guys at libGDX. Basically, with a quick command line, you can package your jar into a native executable for windows, mac, and linux. Whats nice is this solution embeds any JRE that you choose. Big thanks to the libGDX guys!

Android WiFi Debugging

According to a post on xda-developers, you can enable ADB over Wi-Fi from the device with the commands:

su
setprop service.adb.tcp.port 5555
stop adbd
start adbd

And you can disable it and return ADB to listening on USB with

setprop service.adb.tcp.port -1
stop adbd
start adbd

From a computer, if you have USB access already

It is even easier to switch to using Wi-Fi, if you already have USB. From a command line on the computer that has the device connected via USB, issue the commands

adb tcpip 5555
adb connect 192.168.0.101:5555

Be sure to replace 192.168.0.101 with the IP address that is actually assigned to your device.

Photo Collage Layout Algorithm

I’ve been thinking about writing an Android app that lets you view the photos on your phone in a new and different way. The idea is to cluster together images that are taken in close proximity to each other by time and location. I noticed from my own experience that I usually take pictures in sessions and each photo in the session is usually taken within 15 minutes.

So I have the general idea for how to cluster together my photos, now I need an interesting image layout algorithm. I stumbled upon a paper published by HP that outlines what they call the BRIC (Block Recursive Image Composition) algorithm. Check out section 4 for more details.

I wrote my own implementation of the BRIC algorithm in an Android app. Here are a few screenshots. I think it works pretty well.

Fix Debugging GDB Symbols

I was doing some C++ debugging on Ubuntu and noticed to find that non of the local symbols were being displayed in GDB. The only symbol available was std::__ioinit. After some digging I found the solution was to add -gdwarf-2 to the compiler command line:

g++ -g -gdwarf-2

Turns out this is because GCC 4.8+ now generates DWARF4 debugging symbols whereas older version of GCC generated DWARF2 symbols. The problem was my older version of GDB did not know how to use the newer DWARF format.

As noted in GCC 4.8 Release Notes:

DWARF4 is now the default when generating DWARF debug information. When -g is used on a platform that uses DWARF debugging information, GCC will now default to -gdwarf-4 -fno-debug-types-section.
GDB 7.5, Valgrind 3.8.0 and elfutils 0.154 debug information consumers support DWARF4 by default. Before GCC 4.8 the default version used was DWARF2. To make GCC 4.8 generate an older DWARF version use -g together with -gdwarf-2 or -gdwarf-3. The default for Darwin and VxWorks is still -gdwarf-2 -gstrict-dwarf.