Wechat: yu389741| Email: gisdqy@163.com

Shop:https://www.giserdqy.com/shop

编译Android版本的GDAL库


    GDAL(Geospatial Data Abstraction Library)(https://www.gdal.org/)是一个在X/MIT许可协议下的开源栅格空间数据转换库。GDAL功能很强大,支持很多数据格式,使用方便,是GIS开发的不二之选。GDAL库支持多种操作系统,当然也包括Android,然而其官方的Android编译指南,确实写的不明不白,搞不清咋回事,可能是太旧了吧。于是乎我就在Linux下(Windows下的NDK工具貌似不太好用)摸索的一下GDAL的编译,方法记录如下。

 

1.创建独立工具链

创建一个独立的NDK工具链,具体参考http://blog.csdn.net/suningning/article/details/74510125

按照需要创建工具链,比如我创建了arm和arm64架构两个,建议带上-lstdc++选项 。

把bin目录加入PATH

 

2.configure

进入GDAL源码目录,构建arm架构的库,执行下面的configure代码,–prefix指定了要安装的路径,安装实际情况修改。同时还可以指定需要哪些模块,不需要哪些模块。

如果构建arm64架构,下面的代码开头的CFLAGS=”-mthumb” CXXFLAGS=”-mthumb”要去掉,host部分改成–host=aarch64-linux-android即可。

CFLAGS="-mthumb" CXXFLAGS="-mthumb" LIBS="-lstdc++" ./configure --prefix=/home/zouleid/gdal/android --with-threads --with-ogr --host=arm-linux-androideabi  --without-geos --with-libz=internal --with-png=internal --with-libtiff=internal --with-geotiff=internal --with-jpeg=internal --with-sqlite3=yes -without-libtool -with-oci=no --with-xerces=no --with-expat=no --with-libkml=no --without-jpeg12 --without-bsb --without-grib --without-openfilegdb --without--filegdb --without-pam  --without-pdf --without-sentinel2 --without-ctg --without-kmlsuperoverlay --without-wcs --without-vdv --without-dgn --without-dwg

如果configure提示出错,可能是NDK工具链没有加入到环境变量。

configure成功后,可以看到详细的模块信息。

3.make

直接make,开始编译。编译过程中经常会出问题,跟进去解决一下即可,一般不难。

不过有个经验,使用新的GDAL版本,编译出错的可能性较小。比如我用2.3版的源码编译没有出过错误,2.2版的需要改一些源码兼容性错误,1系列的源码就更费劲了。

常见错误:‘to_string’ was not declared in this scope

这个错误其实很简单,打开报错文件的源代码就可以发现。NDK用的是gcc 4.9版本,好像没有to_string函数,源码虽然对to_string进行了处理,但是添加的宏(见下图红框)没处理gcc 4.9,所以,把这个宏处理一下就好。

常见错误:apps目录下代码编译错误

这个报错完全不用管,这是GDAL库构建完成后,构建可执行工具时出错了。这些可执行工具不需要,也没法在Android上使用,编译错误也就不用管了,反正我要的GDAL库已经有了。如果make到这个阶段,就可以当成是构建完成了。

 

4.创建动态链接库so

构建完成了,先检查一下文件

经过刚才的构建,生成了一个静态库libgdal.a,如果你只需要静态库,到这里就算可以了。可我需要动态库so文件,咋办?

这里我们可以修改一下下 GUNmakefile文件:

打开GUNmakefile文件,找到下面的部分

force-lib:
	$(AR) r $(GDAL_LIB) $(GDAL_OBJ)
	$(RANLIB) $(GDAL_LIB)
	$(LD_SHARED) $(GDAL_SLIB_SONAME) $(GDAL_OBJ) $(GDAL_LIBS) $(LDFLAGS) $(LIBS) \
		-o $(GDAL_SLIB)

将其修改为:

force-lib:
	$(AR) r $(GDAL_LIB) $(GDAL_OBJ)
	$(RANLIB) $(GDAL_LIB)
#	$(LD_SHARED) $(GDAL_SLIB_SONAME) $(GDAL_OBJ) $(GDAL_LIBS) $(LDFLAGS) $(LIBS) \
#		-o $(GDAL_SLIB)
	arm-linux-androideabi-g++ \
	--sysroot=/home/public/Android/android-ndk-r14b/platforms/android-22/arch-arm/  \
	-Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl,-soname,libgdal222.so -o libgdal222.so \
	$(GDAL_OBJ)  \
	-L/home/public/Android/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a  \
	-L/home/public/Android/android-ndk-r14b/platforms/android-22/arch-arm/usr/lib  \
	-lgnustl_shared -llog -lz -lm -ldl -lc -lgcc 

上面其实是用g++生成了一个名为libgdal222.so的动态链接库文件。上面的代码不要直接抄,要自己改。上面的代码设置了sysroot路径和另外两个路径,以及生成动态链接库的名字,这些都要根据需要修改。

然后,“make force-lib”即可。

如果构建arm64架构,对应的修改编译器、路径就好了。

我构建出来的arm架构的libgdal222.so有21M大,如果不需要调试,可以strip一下,就只剩15M了。

xxx@xxx-PC:~/gdal/gdal-2.3.1$ ls -l libgdal222.so
-rwxr-xr-x 1 xxx xxx 22053740 8月  10 20:26 libgdal222.so
xxx@xxx-PC:~/gdal/gdal-2.3.1$ cp libgdal222.so libgdal222.bak.so
xxx@xxx-PC:~/gdal/gdal-2.3.1$ arm-linux-androideabi-strip libgdal222.so
xxx@xxx-PC:~/gdal/gdal-2.3.1$ ls -l libgdal222.so
-rwxr-xr-x 1 xxx xxx 16715060 8月  10 20:27 libgdal222.so

注意:这样编译出来的动态链接库so需要libgnustl_shared.so,这个文件在NDK里有,按照你要的架构拷贝出来(其实上面修改makefile的时候已经出现过它的路径了)。

 

5.make install

make完了make install,构建出来的结果就被安装在了构建时–prefix指定的路径中。

不用多说了吧,如果自己生成的so没进去,就自己拷贝进去。

 

6.其他说明

其他的事情以后再补充吧。

转载自:https://blog.csdn.net/zzzzllll2006/article/details/81543896