Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NDK build of spatialite?

I'm attempting to build a copy of sqlite with spatialite extensions. I've seen the one or two related posts online related to this issue, but no one seems to have gone all the way.

I've downloaded the spatialite amalgamation, GEOS and PROJ sources. I've created empty Android projects and moved the uncompressed files into the jni/ directory. The wall I'm running into now is creating the jni/Android.mk file. Does anyone have an example for the GEOS or PROJ dependencies? Has anyone been able to work through this process since the last stackexchange question linked to above?

like image 555
magneticMonster Avatar asked Feb 28 '11 17:02

magneticMonster


1 Answers

I've set things up to compile spatialite as a shared library, and geos and proj as static libs (statically linked with spatialite). These also need libiconv (AFAIK) since the NDK libc doesn't provide iconv.h.

Fortunately, all of these are LGPL or compatible, so it's safe to include these in your app without fear of license issues.

NOTE: You need to run a './configure' first, inside both libiconv and libspatialite in order to generate headers. This requires 'autoconf' be installed.

Also note, this is on Linux (Ubuntu 10.10).

GEOS can't be built and linked in right now because C++ support for STL is completely missing in the NDK. If anyone can come up with a solution to building GEOS, let us know! I'm not sure how critical it is to have the advanced functions in GEOS, but it saves over 1MB of library size leaving it out according to the README.

Here's my main 'jni/Android.mk'. It could be split up into multiple files but I didn't bother cause I'm lazy :-)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := iconv
LOCAL_CFLAGS    := \
    -Wno-multichar \
    -D_ANDROID \
    -DLIBDIR="\"c\"" \
    -DBUILDING_LIBICONV \
    -DIN_LIBRARY
LOCAL_C_INCLUDES := \
    libiconv-1.13.1 \
    libiconv-1.13.1/include \
    libiconv-1.13.1/lib \
    libiconv-1.13.1/libcharset/include
LOCAL_SRC_FILES := \
    libiconv-1.13.1/lib/iconv.c \
    libiconv-1.13.1/lib/relocatable.c \
    libiconv-1.13.1/libcharset/lib/localcharset.c
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := proj
LOCAL_C_INCLUDES := proj-4.7.0/src
LOCAL_LDLIBS := -lm
# this list was generated with:
#   find proj-4.7.0/ -name "*.c" | grep -Ev "tests|doc" | sort | awk '{ print "\t"$1" \\" }'
LOCAL_SRC_FILES := \
    proj-4.7.0/src/aasincos.c \
    proj-4.7.0/src/adjlon.c \
    proj-4.7.0/src/bch2bps.c \
    proj-4.7.0/src/bchgen.c \
    proj-4.7.0/src/biveval.c \
    proj-4.7.0/src/cs2cs.c \
    proj-4.7.0/src/dmstor.c \
    proj-4.7.0/src/emess.c \
    proj-4.7.0/src/gen_cheb.c \
    proj-4.7.0/src/geocent.c \
    proj-4.7.0/src/geod.c \
    proj-4.7.0/src/geod_for.c \
    proj-4.7.0/src/geod_inv.c \
    proj-4.7.0/src/geod_set.c \
    proj-4.7.0/src/jniproj.c \
    proj-4.7.0/src/mk_cheby.c \
    proj-4.7.0/src/nad2bin.c \
    proj-4.7.0/src/nad2nad.c \
    proj-4.7.0/src/nad_cvt.c \
    proj-4.7.0/src/nad_init.c \
    proj-4.7.0/src/nad_intr.c \
    proj-4.7.0/src/PJ_aea.c \
    proj-4.7.0/src/PJ_aeqd.c \
    proj-4.7.0/src/PJ_airy.c \
    proj-4.7.0/src/PJ_aitoff.c \
    proj-4.7.0/src/pj_apply_gridshift.c \
    proj-4.7.0/src/PJ_august.c \
    proj-4.7.0/src/pj_auth.c \
    proj-4.7.0/src/PJ_bacon.c \
    proj-4.7.0/src/PJ_bipc.c \
    proj-4.7.0/src/PJ_boggs.c \
    proj-4.7.0/src/PJ_bonne.c \
    proj-4.7.0/src/PJ_cass.c \
    proj-4.7.0/src/PJ_cc.c \
    proj-4.7.0/src/PJ_cea.c \
    proj-4.7.0/src/PJ_chamb.c \
    proj-4.7.0/src/PJ_collg.c \
    proj-4.7.0/src/PJ_crast.c \
    proj-4.7.0/src/pj_datums.c \
    proj-4.7.0/src/pj_datum_set.c \
    proj-4.7.0/src/PJ_denoy.c \
    proj-4.7.0/src/pj_deriv.c \
    proj-4.7.0/src/PJ_eck1.c \
    proj-4.7.0/src/PJ_eck2.c \
    proj-4.7.0/src/PJ_eck3.c \
    proj-4.7.0/src/PJ_eck4.c \
    proj-4.7.0/src/PJ_eck5.c \
    proj-4.7.0/src/pj_ellps.c \
    proj-4.7.0/src/pj_ell_set.c \
    proj-4.7.0/src/PJ_eqc.c \
    proj-4.7.0/src/PJ_eqdc.c \
    proj-4.7.0/src/pj_errno.c \
    proj-4.7.0/src/pj_factors.c \
    proj-4.7.0/src/PJ_fahey.c \
    proj-4.7.0/src/PJ_fouc_s.c \
    proj-4.7.0/src/pj_fwd.c \
    proj-4.7.0/src/PJ_gall.c \
    proj-4.7.0/src/pj_gauss.c \
    proj-4.7.0/src/pj_geocent.c \
    proj-4.7.0/src/PJ_geos.c \
    proj-4.7.0/src/PJ_gins8.c \
    proj-4.7.0/src/PJ_gnom.c \
    proj-4.7.0/src/PJ_gn_sinu.c \
    proj-4.7.0/src/PJ_goode.c \
    proj-4.7.0/src/pj_gridinfo.c \
    proj-4.7.0/src/pj_gridlist.c \
    proj-4.7.0/src/PJ_gstmerc.c \
    proj-4.7.0/src/PJ_hammer.c \
    proj-4.7.0/src/PJ_hatano.c \
    proj-4.7.0/src/PJ_imw_p.c \
    proj-4.7.0/src/pj_init.c \
    proj-4.7.0/src/pj_initcache.c \
    proj-4.7.0/src/pj_inv.c \
    proj-4.7.0/src/PJ_krovak.c \
    proj-4.7.0/src/PJ_labrd.c \
    proj-4.7.0/src/PJ_laea.c \
    proj-4.7.0/src/PJ_lagrng.c \
    proj-4.7.0/src/PJ_larr.c \
    proj-4.7.0/src/PJ_lask.c \
    proj-4.7.0/src/pj_latlong.c \
    proj-4.7.0/src/PJ_lcca.c \
    proj-4.7.0/src/PJ_lcc.c \
    proj-4.7.0/src/pj_list.c \
    proj-4.7.0/src/PJ_loxim.c \
    proj-4.7.0/src/PJ_lsat.c \
    proj-4.7.0/src/pj_malloc.c \
    proj-4.7.0/src/PJ_mbtfpp.c \
    proj-4.7.0/src/PJ_mbtfpq.c \
    proj-4.7.0/src/PJ_mbt_fps.c \
    proj-4.7.0/src/PJ_merc.c \
    proj-4.7.0/src/PJ_mill.c \
    proj-4.7.0/src/pj_mlfn.c \
    proj-4.7.0/src/PJ_mod_ster.c \
    proj-4.7.0/src/PJ_moll.c \
    proj-4.7.0/src/pj_msfn.c \
    proj-4.7.0/src/pj_mutex.c \
    proj-4.7.0/src/PJ_nell.c \
    proj-4.7.0/src/PJ_nell_h.c \
    proj-4.7.0/src/PJ_nocol.c \
    proj-4.7.0/src/PJ_nsper.c \
    proj-4.7.0/src/PJ_nzmg.c \
    proj-4.7.0/src/PJ_ob_tran.c \
    proj-4.7.0/src/PJ_ocea.c \
    proj-4.7.0/src/PJ_oea.c \
    proj-4.7.0/src/PJ_omerc.c \
    proj-4.7.0/src/pj_open_lib.c \
    proj-4.7.0/src/PJ_ortho.c \
    proj-4.7.0/src/pj_param.c \
    proj-4.7.0/src/pj_phi2.c \
    proj-4.7.0/src/PJ_poly.c \
    proj-4.7.0/src/pj_pr_list.c \
    proj-4.7.0/src/PJ_putp2.c \
    proj-4.7.0/src/PJ_putp3.c \
    proj-4.7.0/src/PJ_putp4p.c \
    proj-4.7.0/src/PJ_putp5.c \
    proj-4.7.0/src/PJ_putp6.c \
    proj-4.7.0/src/pj_qsfn.c \
    proj-4.7.0/src/pj_release.c \
    proj-4.7.0/src/PJ_robin.c \
    proj-4.7.0/src/PJ_rpoly.c \
    proj-4.7.0/src/PJ_sconics.c \
    proj-4.7.0/src/PJ_somerc.c \
    proj-4.7.0/src/PJ_sterea.c \
    proj-4.7.0/src/PJ_stere.c \
    proj-4.7.0/src/pj_strerrno.c \
    proj-4.7.0/src/PJ_sts.c \
    proj-4.7.0/src/PJ_tcc.c \
    proj-4.7.0/src/PJ_tcea.c \
    proj-4.7.0/src/PJ_tmerc.c \
    proj-4.7.0/src/PJ_tpeqd.c \
    proj-4.7.0/src/pj_transform.c \
    proj-4.7.0/src/pj_tsfn.c \
    proj-4.7.0/src/pj_units.c \
    proj-4.7.0/src/PJ_urm5.c \
    proj-4.7.0/src/PJ_urmfps.c \
    proj-4.7.0/src/pj_utils.c \
    proj-4.7.0/src/PJ_vandg2.c \
    proj-4.7.0/src/PJ_vandg4.c \
    proj-4.7.0/src/PJ_vandg.c \
    proj-4.7.0/src/PJ_wag2.c \
    proj-4.7.0/src/PJ_wag3.c \
    proj-4.7.0/src/PJ_wag7.c \
    proj-4.7.0/src/PJ_wink1.c \
    proj-4.7.0/src/PJ_wink2.c \
    proj-4.7.0/src/pj_zpoly1.c \
    proj-4.7.0/src/proj.c \
    proj-4.7.0/src/proj_mdist.c \
    proj-4.7.0/src/proj_rouss.c \
    proj-4.7.0/src/p_series.c \
    proj-4.7.0/src/rtodms.c \
    proj-4.7.0/src/vector1.c
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := spatialite
LOCAL_CFLAGS    := -D__ANDROID__ -DOMIT_GEOS=1 -Dfdatasync=fsync
LOCAL_C_INCLUDES := \
    libiconv-1.13.1/include \
    libiconv-1.13.1/libcharset/include \
    geos-3.2.2/source/headers \
    geos-3.2.2/capi \
    proj-4.7.0/src
LOCAL_SRC_FILES := \
    ./libspatialite-amalgamation-2.3.1/spatialite.c \
    ./libspatialite-amalgamation-2.3.1/sqlite3.c
LOCAL_STATIC_LIBRARIES := iconv proj
include $(BUILD_SHARED_LIBRARY)

With this you'll need to apply some small patches to the sources to get things pulling in the right headers. The Mac build was close but using -D_APPLE_ caused some other weirdness. I ended up just patching up the parts of libiconv and spatialite that I needed to:

diff --git a/android/jni/libiconv-1.13.1/libcharset/lib/localcharset.c b/android/jni/libiconv-1.13.1/libcharset/lib/localcharset.c
index 434fc7c..44b087d 100644
--- a/android/jni/libiconv-1.13.1/libcharset/lib/localcharset.c
+++ b/android/jni/libiconv-1.13.1/libcharset/lib/localcharset.c
@@ -44,7 +44,7 @@
 # endif
 #endif

-#if !defined WIN32_NATIVE
+#if !defined(WIN32_NATIVE) && !defined(__ANDROID__)
 # if HAVE_LANGINFO_CODESET
 #  include <langinfo.h>
 # else
@@ -328,7 +328,7 @@ locale_charset (void)
   const char *codeset;
   const char *aliases;

-#if !(defined WIN32_NATIVE || defined OS2)
+#if !(defined WIN32_NATIVE || defined OS2 || defined __ANDROID__)

 # if HAVE_LANGINFO_CODESET

diff --git a/android/jni/libspatialite-amalgamation-2.3.1/spatialite.c b/android/jni/libspatialite-amalgamation-2.3.1/spatialite.c
index 5fed6f0..d482ecc 100644
--- a/android/jni/libspatialite-amalgamation-2.3.1/spatialite.c
+++ b/android/jni/libspatialite-amalgamation-2.3.1/spatialite.c
@@ -72,7 +72,7 @@ extern const char * locale_charset (void);
 #include <localcharset.h>
 #endif /* end localcharset */
 #else /* not WINDOWS */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
 #include <iconv.h>
 #include <localcharset.h>
 #else /* not Mac OsX */
@@ -7508,7 +7508,7 @@ gaiaCleanSqlString (char *value)
 #define LIBCHARSET_STATIC
 /* #include <localcharset.h> */
 #else /* not MINGW32 - WIN32 */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
 /* #include <iconv.h> */
 /* #include <localcharset.h> */
 #else /* not Mac OsX */
@@ -7526,7 +7526,7 @@ gaiaGetLocaleCharset ()
 #if defined(__MINGW32__) || defined(_WIN32)
     return locale_charset ();
 #else /* not MINGW32 - WIN32 */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
     return locale_charset ();
 #else /* not Mac OsX */
     return nl_langinfo (CODESET);
@@ -13896,7 +13896,7 @@ gaiaPolygonize (gaiaGeomCollPtr geom_org, int force_multipolygon)
 #define LIBCHARSET_STATIC
 /* #include <localcharset.h> */
 #else /* not MINGW32 */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
 /* #include <iconv.h> */
 /* #include <localcharset.h> */
 #else /* not Mac OsX */

And here's the output:

mark@beast:~/Code/android-spatialite/jni$ ndk-build 
Compile thumb  : spatialite <= spatialite.c
Compile thumb  : spatialite <= sqlite3.c
/home/mark/Code/android-spatialite/jni/./libspatialite-amalgamation-2.3.1/sqlite3.c: In function 'unixDlError':
/home/mark/Code/android-spatialite/jni/./libspatialite-amalgamation-2.3.1/sqlite3.c:24986: warning: assignment discards qualifiers from pointer target type
Compile thumb  : iconv <= iconv.c
Compile thumb  : iconv <= relocatable.c
Compile thumb  : iconv <= localcharset.c
StaticLibrary  : libiconv.a
Compile thumb  : proj <= aasincos.c
Compile thumb  : proj <= adjlon.c
Compile thumb  : proj <= bch2bps.c
Compile thumb  : proj <= bchgen.c
Compile thumb  : proj <= biveval.c
Compile thumb  : proj <= cs2cs.c
Compile thumb  : proj <= dmstor.c
Compile thumb  : proj <= emess.c
Compile thumb  : proj <= gen_cheb.c
Compile thumb  : proj <= geocent.c
Compile thumb  : proj <= geod.c
Compile thumb  : proj <= geod_for.c
Compile thumb  : proj <= geod_inv.c
Compile thumb  : proj <= geod_set.c
Compile thumb  : proj <= jniproj.c
Compile thumb  : proj <= mk_cheby.c
Compile thumb  : proj <= nad2bin.c
Compile thumb  : proj <= nad2nad.c
Compile thumb  : proj <= nad_cvt.c
Compile thumb  : proj <= nad_init.c
Compile thumb  : proj <= nad_intr.c
Compile thumb  : proj <= PJ_aea.c
Compile thumb  : proj <= PJ_aeqd.c
Compile thumb  : proj <= PJ_airy.c
Compile thumb  : proj <= PJ_aitoff.c
Compile thumb  : proj <= pj_apply_gridshift.c
Compile thumb  : proj <= PJ_august.c
Compile thumb  : proj <= pj_auth.c
Compile thumb  : proj <= PJ_bacon.c
Compile thumb  : proj <= PJ_bipc.c
Compile thumb  : proj <= PJ_boggs.c
Compile thumb  : proj <= PJ_bonne.c
Compile thumb  : proj <= PJ_cass.c
Compile thumb  : proj <= PJ_cc.c
Compile thumb  : proj <= PJ_cea.c
Compile thumb  : proj <= PJ_chamb.c
Compile thumb  : proj <= PJ_collg.c
Compile thumb  : proj <= PJ_crast.c
Compile thumb  : proj <= pj_datums.c
Compile thumb  : proj <= pj_datum_set.c
Compile thumb  : proj <= PJ_denoy.c
Compile thumb  : proj <= pj_deriv.c
Compile thumb  : proj <= PJ_eck1.c
Compile thumb  : proj <= PJ_eck2.c
Compile thumb  : proj <= PJ_eck3.c
Compile thumb  : proj <= PJ_eck4.c
Compile thumb  : proj <= PJ_eck5.c
Compile thumb  : proj <= pj_ellps.c
Compile thumb  : proj <= pj_ell_set.c
Compile thumb  : proj <= PJ_eqc.c
Compile thumb  : proj <= PJ_eqdc.c
Compile thumb  : proj <= pj_errno.c
Compile thumb  : proj <= pj_factors.c
Compile thumb  : proj <= PJ_fahey.c
Compile thumb  : proj <= PJ_fouc_s.c
Compile thumb  : proj <= pj_fwd.c
Compile thumb  : proj <= PJ_gall.c
Compile thumb  : proj <= pj_gauss.c
Compile thumb  : proj <= pj_geocent.c
Compile thumb  : proj <= PJ_geos.c
Compile thumb  : proj <= PJ_gins8.c
Compile thumb  : proj <= PJ_gnom.c
Compile thumb  : proj <= PJ_gn_sinu.c
Compile thumb  : proj <= PJ_goode.c
Compile thumb  : proj <= pj_gridinfo.c
Compile thumb  : proj <= pj_gridlist.c
Compile thumb  : proj <= PJ_gstmerc.c
Compile thumb  : proj <= PJ_hammer.c
Compile thumb  : proj <= PJ_hatano.c
Compile thumb  : proj <= PJ_imw_p.c
Compile thumb  : proj <= pj_init.c
Compile thumb  : proj <= pj_initcache.c
Compile thumb  : proj <= pj_inv.c
Compile thumb  : proj <= PJ_krovak.c
Compile thumb  : proj <= PJ_labrd.c
Compile thumb  : proj <= PJ_laea.c
Compile thumb  : proj <= PJ_lagrng.c
Compile thumb  : proj <= PJ_larr.c
Compile thumb  : proj <= PJ_lask.c
Compile thumb  : proj <= pj_latlong.c
Compile thumb  : proj <= PJ_lcca.c
Compile thumb  : proj <= PJ_lcc.c
Compile thumb  : proj <= pj_list.c
Compile thumb  : proj <= PJ_loxim.c
Compile thumb  : proj <= PJ_lsat.c
Compile thumb  : proj <= pj_malloc.c
Compile thumb  : proj <= PJ_mbtfpp.c
Compile thumb  : proj <= PJ_mbtfpq.c
Compile thumb  : proj <= PJ_mbt_fps.c
Compile thumb  : proj <= PJ_merc.c
Compile thumb  : proj <= PJ_mill.c
Compile thumb  : proj <= pj_mlfn.c
Compile thumb  : proj <= PJ_mod_ster.c
Compile thumb  : proj <= PJ_moll.c
Compile thumb  : proj <= pj_msfn.c
Compile thumb  : proj <= pj_mutex.c
Compile thumb  : proj <= PJ_nell.c
Compile thumb  : proj <= PJ_nell_h.c
Compile thumb  : proj <= PJ_nocol.c
Compile thumb  : proj <= PJ_nsper.c
Compile thumb  : proj <= PJ_nzmg.c
Compile thumb  : proj <= PJ_ob_tran.c
Compile thumb  : proj <= PJ_ocea.c
Compile thumb  : proj <= PJ_oea.c
Compile thumb  : proj <= PJ_omerc.c
Compile thumb  : proj <= pj_open_lib.c
Compile thumb  : proj <= PJ_ortho.c
Compile thumb  : proj <= pj_param.c
Compile thumb  : proj <= pj_phi2.c
Compile thumb  : proj <= PJ_poly.c
Compile thumb  : proj <= pj_pr_list.c
Compile thumb  : proj <= PJ_putp2.c
Compile thumb  : proj <= PJ_putp3.c
Compile thumb  : proj <= PJ_putp4p.c
Compile thumb  : proj <= PJ_putp5.c
Compile thumb  : proj <= PJ_putp6.c
Compile thumb  : proj <= pj_qsfn.c
Compile thumb  : proj <= pj_release.c
Compile thumb  : proj <= PJ_robin.c
Compile thumb  : proj <= PJ_rpoly.c
Compile thumb  : proj <= PJ_sconics.c
Compile thumb  : proj <= PJ_somerc.c
Compile thumb  : proj <= PJ_sterea.c
Compile thumb  : proj <= PJ_stere.c
Compile thumb  : proj <= pj_strerrno.c
Compile thumb  : proj <= PJ_sts.c
Compile thumb  : proj <= PJ_tcc.c
Compile thumb  : proj <= PJ_tcea.c
Compile thumb  : proj <= PJ_tmerc.c
Compile thumb  : proj <= PJ_tpeqd.c
Compile thumb  : proj <= pj_transform.c
Compile thumb  : proj <= pj_tsfn.c
Compile thumb  : proj <= pj_units.c
Compile thumb  : proj <= PJ_urm5.c
Compile thumb  : proj <= PJ_urmfps.c
Compile thumb  : proj <= pj_utils.c
Compile thumb  : proj <= PJ_vandg2.c
Compile thumb  : proj <= PJ_vandg4.c
Compile thumb  : proj <= PJ_vandg.c
Compile thumb  : proj <= PJ_wag2.c
Compile thumb  : proj <= PJ_wag3.c
Compile thumb  : proj <= PJ_wag7.c
Compile thumb  : proj <= PJ_wink1.c
Compile thumb  : proj <= PJ_wink2.c
Compile thumb  : proj <= pj_zpoly1.c
Compile thumb  : proj <= proj.c
Compile thumb  : proj <= proj_mdist.c
Compile thumb  : proj <= proj_rouss.c
Compile thumb  : proj <= p_series.c
Compile thumb  : proj <= rtodms.c
Compile thumb  : proj <= vector1.c
StaticLibrary  : libproj.a
SharedLibrary  : libspatialite.so
Install        : libspatialite.so => libs/armeabi/libspatialite.so

The resulting library:

$ ls -l ../libs/armeabi/libspatialite.so 
-rwxr-xr-x 1 mark mark 1560744 2011-03-13 22:23 ../libs/armeabi/libspatialite.so
like image 183
Mark Renouf Avatar answered Sep 27 '22 17:09

Mark Renouf