因为mapnik需要部分Boost模块的支持,所以需要编译Boost库。Boost直接在Windows或者Linux下编译并不难,几条指令可以搞定,但是对于交叉编译,正如本文将要阐述的使用NDK进行编译,确实是比较头疼。借助万能的Google和Baidu,我将看到的方法做以整理并进行了亲测。
不过在这之前,我想阐明一个误区,也是给自己补了个课。就是Boost库在使用的时候,并不是都需要编译的。有一小部分和平台相关的模块必须要编译,大部分直接引用头文件即可以使用。毕竟Boost太过庞大,全部编译浪费时间,按需使用最佳。以下是从Boost官网摘录的说明,在此不做翻译了,这点单词对码农来说,不是事。
The only Boost libraries that must be built separately are:
A few libraries have optional separately-compiled binaries:
接下来介绍编译步骤,我是在Windows下使用NDK编译,所以选择了Cygwin的环境,纯Linux下方法大同小异。
NDK版本:官方版 R10c
Boost版本:1.57
1、下载boost_1_57_0.tar.gz,将其放到Cygwin虚拟的Linux目录下,比如/usr/。
2、打开Cygwin,利用tar zxvf指令将boost_1_57_0.tar.gz解压。
3、cd到解压后的Boost根目录下,执行 ./bootstrap.sh,生成boost编译工具。
4、用文本编辑器打开根目录下的project-config.jam文件,修改为如下内容:
import os ;
if [ os.name ] = CYGWIN || [ os.name ] = NT {
androidPlatform = windows ;
}
else if [ os.name ] = LINUX {
androidPlatform = linux-x86_64 ;
}
else if [ os.name ] = MACOSX {
androidPlatform = darwin-x86 ;
}
ANDROID_NDK = <实际的NDK路径> ;
using gcc : android4.9 : $(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-g++ :
<archiver>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ar
<ranlib>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ranlib
<compileflags>-I$(ANDROID_NDK)/platforms/android-19/arch-arm/usr/include
<compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/4.9/include
<compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include
<compileflags>-fexceptions
<compileflags>-frtti
<compileflags>-fpic
<compileflags>-ffunction-sections
<compileflags>-funwind-tables
<compileflags>-D__ARM_ARCH_5__
<compileflags>-D__ARM_ARCH_5T__
<compileflags>-D__ARM_ARCH_5E__
<compileflags>-D__ARM_ARCH_5TE__
<compileflags>-Wno-psabi
<compileflags>-march=armv5te
<compileflags>-mtune=xscale
<compileflags>-msoft-float
<compileflags>-mthumb
<compileflags>-Os
<compileflags>-fomit-frame-pointer
<compileflags>-fno-strict-aliasing
<compileflags>-finline-limit=64
<compileflags>-Wa,--noexecstack
<compileflags>-DANDROID
<compileflags>-D__ANDROID__
<compileflags>-DNDEBUG
<compileflags>-O2
<compileflags>-g
;
project : default-build <toolset>gcc-android4.9 ;
# List of --with-<library> and --without-<library>
# options. If left empty, all libraries will be built.
# Options specified on the command line completely
# override this variable.
libraries = --with-filesystem --with-thread --with-system --with-regex --with-program_options ;
其中NDK路径请根据实际情况填写,另外gcc的版本也可以根据实际情况进行改动。libraries后面跟需要编写的Boost模块,需要哪个加哪个。
Ps:此步骤和网上流传的方法有一些出入,按照其说法是” 修改 boost/tools/build/v2/user-config.jam“,但实际Boost1.57中并没有生成此文件,怀疑可能跟新版本中Boost修改了Bjam有关。
5、执行./b2 toolset=gcc-android4.9 link=static threading=multi target-os=linux --stagedir=android,--stagedir跟生成路径。
至此,就生成了编译好的Boost模块了。其中第四步的代码是我综合了网上的代码和一个开源项目Boost for Android中的代码,里面有很多编译选项我也不是很懂,希望可以和大家交流。不过有一点可以保证,就是顺利的编译。
顺便吐槽下,mapnik确实是个很难配置的东西,我花了很长时间才让它能用,因为需要太多的其他库支持,特别是在Android上使用,需要交叉编译。后面有空我会逐一整理出来,也希望有兴趣的朋友一起交流。