Building GDAL using Android NDK on Linux
Warning! this is still a work in progress!
This procedure was developed on a Linux system using Android NDK r5b and is based on information from this thread: http://groups.google.com/group/android-ndk/browse_thread/thread/9988752f332eff45
Cross compiling GDAL
First, a standalone toolchain is created to make the configure script easier to use. (See android-ndk-r5b/docs/STANDALONE-TOOLCHAIN.html for more details)
~$ android-ndk-r5b/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=android-8-toolchain
Next, the toolchain's bin directory is added to the PATH.
~$ export PATH=$PATH:~/android-8-toolchain/bin/
From the GDAL source directory, configure for cross compiling and make. (This assumes config.guess and config.sub where updated. Latest versions can be found here: http://git.savannah.gnu.org/cgit/config.git/tree/)
Older GDAL versions (before r21653 - includes 1.8.0)
before compiling, patch the source with the patch given at http://trac.osgeo.org/gdal/ticket/3952
Newest GDAL versions after r22958 (including 1.9)
as below, but --without-grib is not needed anymore
All GDAL versions
gdal$ CFLAGS="-mthumb" CXXFLAGS="-mthumb" LIBS="-lsupc++ -lstdc++" \
./configure --host=arm-linux-androideabi --without-grib --prefix=$PROJECT/external/gdal
gdal$ make
gdal$ make install
The $PROJECT variable contains the path to where you want your Android NDK modules to live.
In $PROJECT/external/gdal, an Android.mk file is created with the following contents:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := gdal LOCAL_SRC_FILES := lib/libgdal.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_EXPORT_LDLIBS := -lz include $(PREBUILT_STATIC_LIBRARY)
Using in a JNI library
Here's a HelloGdal app to test the use of the library as part of a JNI component of an Android project.
In the project's jni directory, hello-jdal.cpp was create with the following contents:
#include <jni.h>
#include <ogr_api.h>
#include <sstream>
extern "C" {
JNIEXPORT jstring
JNICALL Java_org_gdal_HelloGdal_stringFromGDAL(JNIEnv*env, jobject thiz);
}
JNIEXPORT jstring
JNICALL Java_org_gdal_HelloGdal_stringFromGDAL(JNIEnv* env, jobject thiz)
{
OGRRegisterAll();
std::ostringstream drivers;
drivers << "OGR Drivers:\n";
for (int i = 0; i < OGRGetDriverCount(); ++i)
drivers << "\t" << OGR_Dr_GetName(OGRGetDriver(i)) << "\n";
return env->NewStringUTF(drivers.str().c_str());
}
(Yes, I know, it's called HelloGdal, yet it lists the OGR drivers. I'll leave it as an exercise to have the GDAL drivers listed)
Here's the corresponding Android.mk file:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-gdal LOCAL_SRC_FILES := hello-gdal.cpp LOCAL_STATIC_LIBRARIES := gdal include $(BUILD_SHARED_LIBRARY) $(call import-module,gdal)
The path to the external GDAL module is set and the library is built using the NDK's build process.
jni$ export NDK_MODULE_PATH=$PROJECT/external jni$ $NDK_ROOT/ndk-build
Finally, the Java portion that uses the JNI library.
package org.gdal;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloGdal extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText( stringFromGDAL() );
setContentView(tv);
}
public native String stringFromGDAL();
static {
System.loadLibrary("hello-gdal");
}
}
Next steps
- build and adapt the Java swig bindings to expose GDAL to the Java portion of an Android application. It needs just one change in typemaps_java.i, here it is done based on GDAL 1.9.2 version: https://github.com/nutiteq/gdal/blob/1.9/gdal/HOWTO_ANDROID.txt
