Android NDK Notes

Some notes on NDK problems I've had to overcome in the last few days, there are bound to be corrections needed, I'll try and update these based on any comments.

Environment variables

Various scripts use different ones to discover the location of the NDK - so don't be surprised when you see ANDROID_NDK, ANDROID_NDK_ROOT, ANDROID_NDK_HOME, or anything else - they mean the same thing, right now I'm using ANDROID_NDK currently.


There are lots of different versions of android_cmake, subtly incompatible, you probably will need to edit scripts. Before trying to use cmake with Android, make sure you can build some apps using the standard tools, or the scripts that come with them This is something I'll probably come back to, as I'm using gradle and right now.

Android Studio

In transition

Android used to use Eclipse and ANT, now it's in transition to Android Studio and Gradle, hence some things don't work, but they can be tweaked - this situation will probably change.

Installing NDK

Has it's own copy of the NDK, you can install it from the preferences in the Android SDK section, if you already installed a copy it won't automatically find it.

Build works when launching from terminal, but not using desktop icon

Android Studio doesn't pick up variables set in '.bashrc' - this means scripts may work if you launch it from a terminal, but not from the desktop.

Taking ages opening project, message about gradle

Android studio downloads this the first time, if you want more information load it from the terminal and you will see some info as it downloads.

Error about "JCenter" when trying to build

This can be because you have a really old version of gradle installed (ie the one that comes with Ubuntu 15.04) - if on Ubuntu you can test this by building using the "gradlew" script in your project, if this works then upgrade gradle - on Ubuntu there is a gradle PPA.

Not picking up settings in

You can add this at the top of your app.gradle
Properties properties = new Properties()
def sdkDir = properties.getProperty('sdk.dir')
def ndkDir = properties.getProperty('ndk.dir')
Then add ndkDir to your ndkBuild section
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine ndkDir + '/ndk-build.cmd', '-C', file('src/main').absolutePath
    } else {
        commandLine ndkDir + '/ndk-build', '-C', file('src/main').absolutePath

Including other files

You can do this like this
include $(LOCAL_PATH)/../assimp/workspaces/Android-NDK/jni/
Make sure to do these includes at the end of your own file  as they may overwrite variables like LOCAL_PATH, also $(call my-dir) returns the name of the latest included file.

No rule to make target

The build couldn't find the mentioned file, if you use a variable like LOCAL_PATH, maybe it was overwritten - see the section on includes

Outputting values from

$(info hi, LOCAL_PATH is $(LOCAL_PATH))
$(warning Uh oh...)
$(error this is the error message that will stop the build process)

Running on a real device

cannot locate symbol “srand”

Android 21 changed the location of some symbols - either set your minimum sdk to 21 and build with that, or have a lower one (e.g. 19) and build with that SDK

Everything else

Expect to do a lot of googling, expect to have to change makefiles. ... look at other projects using the libraries you use and see how they work, good luck !

Up to date on videos

Real lift has got in the way of doing much graphics work recently, however I've now caught up and uploaded a bunch of videos.. (it also took quite a while to get scripts for creating the same videos, with sound working).

Audio Reactive Critters

Graphics experiments

Rendering fat lines with Shoebot

Animating fat lines with Shoebot

Learning about 2D vectors

I have some basic code to find the length of a Bezier Curve and a point along it, I seem to have talked myself into implementing this in Cairo, so that's the next stage, from there path effects and text-on-a-path will be the next stage.

Progress so far

I've been pretty busy so far doing laying the groundwork for my audiovisual project. I've got the architecture worked out, so ones this stage 0 is complete I can start coding it. Uploaded, 2 videos using shoebot... 4 others waiting to be uploaded. Soft Released: vext This makes it easy to use things like wx, gtk, pyqt4 and other, mostly Gui and older Audio libraries in virtualenv. Have been using this successfully with Shoebot for a while. Python 3 support is still TODO, at which point can do a proper release. Working on: Finishing off a tool to make videos with :) Learning About: Bezier Curves (have a Gtk demo app waiting to be uploaded) [Blocking on app to create videos] Cairo OpenGL PPA: Built a Docker Image that can build debian packages, this needs completing so they can be signed and uploaded to the PPA.

Wifi + Moving Country

If you are on linux and having trouble with WIFI in a new country it might be worth letting it know what country you are in - on debian/ubuntu edit the file /etc/default/crda and update the country code.

Daily graphic 2

Todays daily graphic I'm getting familiar with grids (in shoebot), Vector maths from the planar library .. this started from the grid example from shoebot / nodebox. Shoebot Code Below the fold (more…)

Everyday graphic

Not sure how practical it is, but will try and upload a new graphic everyday .. to start with will probably be quite basic :) Here is the first, some moving granual thingies.. Shoebot code:
import random
from math import sin, cos

size(800, 800)

def draw():
    scale(1, 1)
    fill(0.1, 0.2, 0.3)

    for y in xrange(0, HEIGHT, 80):
        wiggle = sin(FRAME * 0.1)
        xs = 2.0 + (cos(y * 0.1) + sin(y) * 8.1)

        distance = 1.0 / HEIGHT * y
        fill(1.0, 1.0-distance, 0, distance)
        for x in xrange(0, 60):
            xpos = ((xs * FRAME-x * 40) % (WIDTH + 40)) - 20
            circle(xpos, y + (wiggle * random.random() * 20.0), 20 + (wiggle * 2.0) * distance * 8.0)

        #xs = -sin(y) * 4.0
        #for x in xrange(0, 60):
        #    circle(WIDTH-xs * WIDTH - FRAME + x * 40, y+40, 20)

Workflow for debugging issues on python on windows with a VM

Recently I had to look at an issue where the behaviour on windows was subtly different to that on linux... unfortunately most potential users are on Windows so it's not good enough to just write them off :) This workflow was quite good for checking python internals on different versions of python and being able to revert things easily. To get things going quickly I use the IE11 VM from microsoft, and download from xdissent That way you just need to enter a command to download it
curl -s | env IEVMS_VERSIONS="11" bash
Next I install all the tools I need before python (we will save the state of the VM before then). makes installing tools easy* Open a command Window as Administrator then install chocolatey:
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString(''))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
Once thats done you can install tools you need - I install everything *except* python:
choco install git conemu
While these are installing start the downloads for python and it's C compiler (remember not to install them yet): Grab python from here: For python 2.7.x you will probably need the VC compiler My app was for PyGtk so I also downloaded that - download anything else you need at this stage. Download your project... Using git or whatever, grab your own project to a directory. Save the VM state. In virtualbox save the machine state, I called mine 'Tools Installed'. From here you can install python + know that you can poke around in the internals, any time you want to check against a different version, just revert the VM to the previous state.   TL;DR - Install all tools except python, grab projects, SNAPSHOT, install python - find bugs. *when it works.

Setting up Backups

A day of Admin .. Spent a good amount of time getting backups setup on ubuntu .. Insynch to backup google drive to my computer - Setup good old Thunderbird to download email to my computer - the trick is to get an an app specific password. Finally, bought cloud backup from SpiderOak it seems quite good from a security point of view, the app itself is a little 'java', but seems to work OK.

Docker and caching apt-get for guests on the same host

Docker is great for isolation, you probably still want some caching, the Dockerfile from extellisys is a great start: Running the above, runs apt-cache-ng and exposes it's port as 3142. This is great for a LAN, if you want to use this for caching on your dev box then read on. If you just want lines to paste into other Dockerfiles, skip to the end.
To avoid surprises I tend to change the "FROM" part of any Ubuntu or Debian based Dockerfiles to use the same distro as the host (in this case "ubuntu:14.10"), this should save a little space too.

Optionally use the cache with Docker guests on the same host.

Desired result - use the cache if available, otherwise don't. Avahi is the usual way to do this, unfortunately it doesn't work easily in between host and guest. We can make our own way of doing this. So all we need to do is find the host IP from another guest - $ route -n | awk '/^ {print $2}' The other part is optionally using a proxy - the undocumented apt.conf.d setting Acquire::http::ProxyAutoDetect is what we want. It runs a discovery script that either outputs an IP of a proxy, or DIRECT if there is none.

Discovery script and setting

/usr/local/bin/apt-ng-host-discover: #!/bin/bash HOST_IP=$(route -n | awk '/^ {print $2}') if nc -w1 -z $HOST_IP 3142; then printf http://$HOST_IP:3142; else printf DIRECT; fi /etc/apt/apt.conf.d/30proxy: Acquire::http::ProxyAutoDetect "/usr/local/bin/apt-ng-host-discover";

Putting it together / tl;dr;

Everything can be munged into 5 lines you paste into your Dockerfile: RUN HOST_IP=$(route -n | awk '/^ {print $2}'); \ echo "#!/bin/bash" > /usr/local/bin/apt-ng-host-discover; \ echo "if nc -w1 -z $HOST_IP 3142; then printf http://$HOST_IP:3142; else printf DIRECT; fi" >> /usr/local/bin/apt-ng-host-discover && \ chmod +x /usr/local/bin/apt-ng-host-discover RUN echo 'Acquire::http::ProxyAutoDetect "/usr/local/bin/apt-ng-host-discover";' > /etc/apt/apt.conf.d/30proxy

Further work

Run the extellisys cache on boot, and disable any other caching ( ).