<span style>Hi everyone,</span><div style><br></div><div style>Some reason, I needed to build gdal for android on windows, so I'll be glad if this helps someone - it's not very obvious.</div><div style><font color="#222222" face="arial, sans-serif">I don't like the script, w</font>hich edits <a href="http://libgdal.la">libgdal.la</a> file, but du<font color="#222222" face="arial, sans-serif">e to the lack of experience with libtool I don't know, how to do it in a better way.</font></div>
<div style><br></div><div style><span style="font-family:Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif">This procedure was developed on a Windows 7 system using Android NDK r7c and is based on information from this manual: </span><a href="http://trac.osgeo.org/gdal/wiki/BuildingForAndroid" target="_blank" style="color:rgb(17,85,204)">http://trac.osgeo.org/gdal/wiki/BuildingForAndroid</a></div>
<div style><br></div>We need: <br> - Android NDK r7c (I think, all the versions from r5b will fit fine, but didn't test it)<br> - Cygwin 1.7 or higher<br> - Gdal 1.9.0 <br><br><br>1. NDK preparation<br>It's useful to have "PATH=$PATH:<path/to/android-ndk-r7c>" in your cygwin .profile, but you can add it manually as the first step after ndk unzip:<br>
$ export PATH=$PATH:/cygdrive/c/dev/Android/android-ndk-r7c<br><br>As in linux, we should create a standalone toolchain somewhere, i made it from the "/cygdrive/c/dev/Android/" directory<br>$ android-ndk-r7c/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=android-8-toolchain<br>
<br>Add toolchain bin directory to PATH:<br>$ export PATH=$PATH:/cygdrive/c/dev/Android/android-8-toolchain/bin<br><br>Since android g++ or gcc can't understand cygwin path like /cygdrive/c/path/to, we need to correct them. Create a file and fill it with:<br>
<br>#! /bin/sh<br><br>#Notice space at the end<br>RUN_COMMAND="/bin/sh " <br><br>if [[ "$1" == "" ]]<br>then exit<br>fi<br><br>for x in "$@"<br>do<br> if [[ ${x: -7} == "libtool" ]] <br>
then <br> RUN_COMMAND=$RUN_COMMAND' '$x<br><br>else <br>if [[ ${x: -11} == "/<a href="http://libgdal.la">libgdal.la</a>" ]]<br> then <br>sed -i.bak 's/libgdal.so.1.16.0 libgdal.so.1 <a href="http://libgdal.so/libgdal.so">libgdal.so/libgdal.so</a> libgdal.so.1 libgdal.so.1.16.0/' $x <br>
fi <br>RUN_COMMAND=$RUN_COMMAND' '${x/\/cygdrive\/c\//C:\/}<br><br> fi<br>done<br><br>$RUN_COMMAND<br><br>I placed this file in "/cygdrive/c/dev/Android/android-8-toolchain/bin" as it's already in the PATH. Script will turn all the "/cygdrive/c/" into "C:/" except libtool invoke command. The sed command will be explained a bit later.<div>
<br><br>2. Gdal configure<br>Go to gdal 1.9.0 source directory. Ndk-build, in future, expect your ndk gdal module to be in path/to/<tag>/, where <tag> is gdal for us, so we use something like "/cygdrive/c/dev/lib/gdal-1.9.0/gdal" as the prefix for our build:<br>
$ CFLAGS="-mthumb" CXXFLAGS="-mthumb" ./configure --host=arm-linux-androideabi --prefix=/cygdrive/c/dev/lib/gdal-1.9.0/gdal<br><br>Note, that we don't need to mention -lstdc++ or -lsupc++. Btw, the last one is not placed in the toolchain since ndk-7 release (it's a known bug).<br>
<br>Now we need to edit GDALMake.opt:<br>After "SHELL = /bin/sh" line add this: "CORRECT = correct_path".<br>Two lines down, change "LIBTOOL = $(SHELL) $(top_builddir)/libtool" to "LIBTOOL = $(CORRECT) $(top_builddir)/libtool"<br>
<br>Now simply make:<br>$ make<br><br>There is a problem with generated <a href="http://libtool.la">libtool.la</a> file - it has line: "library_names='libgdal.so.1.16.0 libgdal.so.1 libgdal.so'", so libgdal.so will be passed to g++. It will fail, but the sed command in the script changes this line to "library_names='libgdal.so libgdal.so.1 libgdal.so.1.16.0'" and it links fine.<br>
<br>Now, just install:<br>$ make install</div><div><br><br>3. Creaing Android application.<br><br>Now just set path to gdal module (path must contain 'gdal' folder - tag name):<br><br>$ export NDK_MODULE_PATH=/cygdrive/c/dev/lib/gdal-1.9.0<br>
<br>In the gdal-tag module directory ($NDK_MODULE_PATH/gdal) create an Android.mk file:<br><br>LOCAL_PATH := $(call my-dir) <br><br>include $(CLEAR_VARS) <br><br>LOCAL_MODULE := gdal <br>LOCAL_SRC_FILES := lib/libgdal.a <br>
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include <br>LOCAL_EXPORT_LDLIBS := -lz <br>include $(PREBUILT_STATIC_LIBRARY)<br><br><br>Create some android app, let it be HelloGdal.<br>In the project's jni directory, create hello-jdal.cpp with the following contents:<br>
<br>#include <jni.h><br>#include <ogr_api.h><br>#include <sstream><br><br>extern "C" {<br>JNIEXPORT jstring<br>JNICALL Java_org_gdal_HelloGdal_stringFromGDAL(JNIEnv*env, jobject thiz);<br>}<br>
<br>JNIEXPORT jstring<br>JNICALL Java_org_gdal_HelloGdal_stringFromGDAL(JNIEnv* env, jobject thiz)<br>{<br>OGRRegisterAll();<br>std::ostringstream drivers;<br>drivers << "OGR Drivers:\n";<br>for (int i = 0; i < OGRGetDriverCount(); ++i)<br>
drivers << "\t" << OGR_Dr_GetName(OGRGetDriver(i)) << "\n";<br><br>return env->NewStringUTF(drivers.str().c_str());<br>}<br><br><br>The corresponding Android.mk, which should be placed in the same folder:<br>
<br>LOCAL_PATH := $(call my-dir)<br><br>include $(CLEAR_VARS)<br><br>LOCAL_MODULE := hello-gdal<br>LOCAL_SRC_FILES := hello-gdal.cpp<br>LOCAL_STATIC_LIBRARIES := gdal<br><br>include $(BUILD_SHARED_LIBRARY)<br>$(call import-module,gdal)<br>
<br><br>You should also create Application.mk with a single line inside:<br>APP_STL := gnustl_shared<br><br>Now, from the jni directory simply run ndk build:<br>$ ndk-build<br><br>Two libraries - libgnustl_shared.so and libhello-gdal.so will be created as result.<br>
<br>Java code of the app:<br><br>package org.gdal; <br><br>import android.app.Activity; <br>import android.os.Bundle; <br>import android.widget.TextView; <br><br>public class HelloGdal extends Activity <br>{ <br> public void onCreate(Bundle savedInstanceState) <br>
{ <br> super.onCreate(savedInstanceState); <br> TextView tv = new TextView(this); <br> tv.setText( stringFromGDAL() ); <br> setContentView(tv); <br> } <br><br> public native String stringFromGDAL(); <br>
<br> static { System.loadLibrary("hello-gdal"); } <br>}<div><br></div><div>-- <br>Best Regards, <br>Petr Kitashov
</div></div>