[gdal-dev] Building GDAL from source for android under cygwin
Petr Kitashov
hilmekrhu at gmail.com
Mon Apr 16 17:42:48 EDT 2012
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/gdal-dev/attachments/20120417/95d73c2c/attachment.html
More information about the gdal-dev
mailing list