注明:以下只对boost c++ 1.47 版本有效,boost c++ 1.52 的filesystem 目前还没有找到编译办法
Boost is almost composed of template and header files. Thus, nothing needs to be built at all most of the time… just include the necessary header files. This is true for smart pointers for example. But a few features of Boost are available through compiled libraries, like the threading module. Let’s see how to do that with the NDK R5!
First, I would like to point out that this solution is based on a discussion from Google Group. To compile boost, do the following (I do it on Ubuntu but this should be similar on Windows with Cygwin):
- The first thing is to download Boost. I am using Boost v1.46.1 in the present post.
- Then untar the archive into your $ANDROID_NDK/sources directory. You should end up with the following
> ls -al $ANDROID_NDK/sources/boost boost doc libs more stage status tools ...
- When uncompressed, open the file “user-config.jam” located in “$ANDROID_NDK/sources/boost/tools/build/v2″. BJam is a custom build tool more or less like make or ant and which is used to build boost. The file user-config.jam is, like its name indicates it, a custom configuration file that can be set-up by Boost users before compilation. Update user-config.jam with the following content:
import os ; if [ os.name ] = CYGWIN || [ os.name ] = NT { androidPlatform = windows ; } else if [ os.name ] = LINUX { androidPlatform = linux-x86 ; } else if [ os.name ] = MACOSX { androidPlatform = darwin-x86 ; } modules.poke : NO_BZIP2 : 1 ; ANDROID_NDK = ../.. ; using gcc : android4.4.3 : $(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-g++ : <compileflags>--sysroot=$(ANDROID_NDK)/platforms/android-9/arch-arm <compileflags>-mthumb <compileflags>-Os <compileflags>-fno-strict-aliasing <compileflags>-O2 <compileflags>-DNDEBUG <compileflags>-g <compileflags>-lstdc++ <compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/include <compileflags>-I$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include <compileflags>-D__GLIBC__ <compileflags>-DBOOST_NO_INTRINSIC_WCHAR_T <compileflags>-DBOOST_FILESYSTEM_VERSION=2 <archiver>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ar <ranlib>$(ANDROID_NDK)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ranlib ;
- Once this is done, launch compilation using the following command line. We need to exclude a few modules which are not working with NDK like the “serialization” module. Indeed NDK does not support wide chars which are required for it. We don’t compile python which requires additional python libs:
bjam --without-python --without-serialization toolset=gcc-android4.4.3 link=static runtime-link=static target-os=linux --stagedir=android
注明:新的boost c++安装方法 用下面的替换上面的
./b2
--without-python --without-serialization toolset=gcc-android4.4.3 link=static runtime-link=static target-os=linux --stagedir=android
- Download the the .tar.gz from http://sourceforge.net/projects/boost/files/boost/1.50.0/
-
Unpack and go into the directory:
tar -xzf boost_1_50_0.tar.gz cd boost_1_50_0
-
Configure (and build
bjam
): 如果这步出现 命令无效,请重新去官网下载.tar文件包,.zip文件包会出现这个问题./bootstrap.sh --prefix=/some/dir/you/would/like/to/prefix
-
Build:
./b2
-
Install:
./b2 install
会出现“libs/filesystem/v2/src/v2_operations.cpp:62:30: error: sys/statvfs.h: No such file or directory” 问题,解决方法是:找到v2_operations.cpp 第62行修改为:
#ifndef ANDROID
# include <sys/statvfs.h>
#else
# include <sys/vfs.h>
# define statvfs statfs
#endif
- The biggest step has been performed. No error should appear on screen after compilation (look for “…failed updating X targets…” message). Now, how to include it in our own project? One of the best solution is to make use of the new import-module feature of NDK R5.
- Create an Android.mk file in $ANDROID_NDK/sources/boost. It needs to contain one module declaration per library. Variable LOCAL_EXPORT_C_INCLUDES is important as it is the one which automatically append boost directory to include file directories. Here, we declared two static libs Boost thread and iostreams. All available libraries can be found in $ANDROID_NDK/sources/boost/android/lib:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= boost_thread LOCAL_SRC_FILES:= android/lib/libboost_thread.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE:= boost_iostreams LOCAL_SRC_FILES:= android/lib/libboost_iostreams.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(PREBUILT_STATIC_LIBRARY)
- To include Boost in an application, we need to link with a STL which supports exception. Hopefully, we don’t need to build one manually anymore as NDK R5 now provides STLport and GNU STL. However, only GNU STL support exceptions right now. But on the opposite to STLport, only static linking is supported. So to make use of GNU STL, just open (or create) your Application.mk file and add (or complete) the two following lines:
... APP_STL = gnustl_static APP_CPPFLAGS = -fexceptions
- Finally, open your Application (not Boost one) Android.mk file, include the boost module and call import-module function:
... LOCAL_STATIC_LIBRARIES := ... boost_thread ... ... $(call import-module,boost)
That’s it! Just include the headers, write your code with boost and run it!
boost::thread bgThread(...); ... bgThread.join();
That’s it! Now enjoy the (almost) full power of Boost…