Hi everyone, 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. I don't like the script, which edits libgdal.la file, but due to the lack of experience with libtool I don't know, how to do it in a better way.
This procedure was developed on a Windows 7 system using Android NDK r7c and is based on information from this manual: http://trac.osgeo.org/gdal/wiki/BuildingForAndroid We need: - Android NDK r7c (I think, all the versions from r5b will fit fine, but didn't test it) - Cygwin 1.7 or higher - Gdal 1.9.0 1. NDK preparation 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: $ export PATH=$PATH:/cygdrive/c/dev/Android/android-ndk-r7c As in linux, we should create a standalone toolchain somewhere, i made it from the "/cygdrive/c/dev/Android/" directory $ android-ndk-r7c/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=android-8-toolchain Add toolchain bin directory to PATH: $ export PATH=$PATH:/cygdrive/c/dev/Android/android-8-toolchain/bin 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: #! /bin/sh #Notice space at the end RUN_COMMAND="/bin/sh " if [[ "$1" == "" ]] then exit fi for x in "$@" do if [[ ${x: -7} == "libtool" ]] then RUN_COMMAND=$RUN_COMMAND' '$x else if [[ ${x: -11} == "/libgdal.la" ]] then sed -i.bak 's/libgdal.so.1.16.0 libgdal.so.1 libgdal.so/libgdal.so libgdal.so.1 libgdal.so.1.16.0/' $x fi RUN_COMMAND=$RUN_COMMAND' '${x/\/cygdrive\/c\//C:\/} fi done $RUN_COMMAND 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. 2. Gdal configure 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: $ CFLAGS="-mthumb" CXXFLAGS="-mthumb" ./configure --host=arm-linux-androideabi --prefix=/cygdrive/c/dev/lib/gdal-1.9.0/gdal 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). Now we need to edit GDALMake.opt: After "SHELL = /bin/sh" line add this: "CORRECT = correct_path". Two lines down, change "LIBTOOL = $(SHELL) $(top_builddir)/libtool" to "LIBTOOL = $(CORRECT) $(top_builddir)/libtool" Now simply make: $ make There is a problem with generated libtool.la 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. Now, just install: $ make install 3. Creaing Android application. Now just set path to gdal module (path must contain 'gdal' folder - tag name): $ export NDK_MODULE_PATH=/cygdrive/c/dev/lib/gdal-1.9.0 In the gdal-tag module directory ($NDK_MODULE_PATH/gdal) create an Android.mk file: 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) Create some android app, let it be HelloGdal. In the project's jni directory, create hello-jdal.cpp 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()); } The corresponding Android.mk, which should be placed in the same folder: 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) You should also create Application.mk with a single line inside: APP_STL := gnustl_shared Now, from the jni directory simply run ndk build: $ ndk-build Two libraries - libgnustl_shared.so and libhello-gdal.so will be created as result. Java code of the app: 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"); } } -- Best Regards, Petr Kitashov
_______________________________________________ gdal-dev mailing list [email protected] http://lists.osgeo.org/mailman/listinfo/gdal-dev
