ひまlab

ひまな時になんか書く。

Android NDKで、Boost 1.52.0を使うために

Androidで、Boost 1.52.0を使う機会があったので、ビルド手順を記録します。

環境

資材

手順

1. CygwinとNDKをセットアップ
2. boostをダウンロード
3. 任意の場所に解凍

    • ここでは、c:\work\boost_1_52_0 を仮定

4. パッチ(boost_1_52_0.patch)をc:\work\を配置して、次のコマンドを実行する

 $ c:\work
 $ patch -p0 boost_1_52_0.patch

5. boost_1_52_0\tools\build\v2\user-config.jamのANDROID_NDK_ROOTを次のように修正

ANDROID_NDK_ROOT = <NDKの配置先>

6. ビルドする

 $ c:\work\boost_1_52_0
 $ ./bootstrap.sh
 $ ./b2 toolset=gcc-android4.6 link=static runtime-link=static target-os=linux –stagedir=android

7. ライブラリが出来上がる

パッチ

boost_1_52_0.patchの中身

diff -ur boost_1_52_0/boost/asio/detail/fenced_block.hpp boost_1_52_0_patched/boost/asio/detail/fenced_block.hpp
--- boost_1_52_0/boost/asio/detail/fenced_block.hpp	2012-07-23 04:03:30.000000000 +0900
+++ boost_1_52_0_patched/boost/asio/detail/fenced_block.hpp	2012-11-21 13:05:11.949629346 +0900
@@ -25,7 +25,7 @@
 # include <boost/asio/detail/macos_fenced_block.hpp>
 #elif defined(__sun)
 # include <boost/asio/detail/solaris_fenced_block.hpp>
-#elif defined(__GNUC__) && defined(__arm__) \
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) \
   && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
 # include <boost/asio/detail/gcc_arm_fenced_block.hpp>
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
@@ -35,7 +35,8 @@
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) \
+  && !defined(ANDROID) && !defined(__ANDROID__)
 # include <boost/asio/detail/gcc_sync_fenced_block.hpp>
 #elif defined(BOOST_WINDOWS) && !defined(UNDER_CE)
 # include <boost/asio/detail/win_fenced_block.hpp>
@@ -55,7 +56,7 @@
 typedef macos_fenced_block fenced_block;
 #elif defined(__sun)
 typedef solaris_fenced_block fenced_block;
-#elif defined(__GNUC__) && defined(__arm__) \
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) \
   && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
 typedef gcc_arm_fenced_block fenced_block;
 #elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
@@ -65,7 +66,8 @@
 #elif defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
-  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) \
+  && !defined(ANDROID) && !defined(__ANDROID__)
 typedef gcc_sync_fenced_block fenced_block;
 #elif defined(BOOST_WINDOWS) && !defined(UNDER_CE)
 typedef win_fenced_block fenced_block;
diff -ur boost_1_52_0/boost/asio/ip/address_v6.hpp boost_1_52_0_patched/boost/asio/ip/address_v6.hpp
--- boost_1_52_0/boost/asio/ip/address_v6.hpp	2012-01-15 05:46:24.000000000 +0900
+++ boost_1_52_0_patched/boost/asio/ip/address_v6.hpp	2012-11-21 13:16:18.257708064 +0900
@@ -11,6 +11,23 @@
 #ifndef BOOST_ASIO_IP_ADDRESS_V6_HPP
 #define BOOST_ASIO_IP_ADDRESS_V6_HPP
 
+// @Moss - Define IPv6 macros
+#if !defined(IN6_IS_ADDR_MULTICAST) 
+#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
+#endif
+
+#if !defined(IN6_IS_ADDR_MC_NODELOCAL)
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0x1))
+#endif
+
+#if !defined(IN6_IS_ADDR_MC_GLOBAL)
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) \
+         && ((((__const uint8_t *) (a))[1] & 0xf) == 0xe))
+#endif
+
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
diff -ur boost_1_52_0/boost/config/user.hpp boost_1_52_0_patched/boost/config/user.hpp
--- boost_1_52_0/boost/config/user.hpp	2004-01-10 04:10:00.000000000 +0900
+++ boost_1_52_0_patched/boost/config/user.hpp	2012-11-21 13:19:15.433681664 +0900
@@ -12,6 +12,9 @@
 //  Use this file to define a site and compiler specific
 //  configuration policy:
 //
+#define __arm__ 1
+#define _REENTRANT 1
+#define _GLIBCXX__PTHREADS 1
 
 // define this to locate a compiler config file:
 // #define BOOST_COMPILER_CONFIG <myheader>
diff -ur boost_1_52_0/boost/detail/endian.hpp boost_1_52_0_patched/boost/detail/endian.hpp
--- boost_1_52_0/boost/detail/endian.hpp	2011-03-29 14:58:48.000000000 +0900
+++ boost_1_52_0_patched/boost/detail/endian.hpp	2012-11-21 13:20:17.925611353 +0900
@@ -31,7 +31,7 @@
 // GNU libc offers the helpful header <endian.h> which defines
 // __BYTE_ORDER
 
-#if defined (__GLIBC__)
+#if defined (__GLIBC__) || defined(ANDROID)
 # include <endian.h>
 # if (__BYTE_ORDER == __LITTLE_ENDIAN)
 #  define BOOST_LITTLE_ENDIAN
diff -ur boost_1_52_0/boost/interprocess/detail/workaround.hpp boost_1_52_0_patched/boost/interprocess/detail/workaround.hpp
--- boost_1_52_0/boost/interprocess/detail/workaround.hpp	2012-09-24 05:17:34.000000000 +0900
+++ boost_1_52_0_patched/boost/interprocess/detail/workaround.hpp	2012-11-21 13:21:17.853633729 +0900
@@ -54,7 +54,7 @@
    #endif
 
    //Check for XSI shared memory objects. They are available in nearly all UNIX platforms
-   #if !defined(__QNXNTO__)
+   #if !defined(__QNXNTO__) && !defined(ANDROID)
       #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
    #endif
 
diff -ur boost_1_52_0/libs/filesystem/src/operations.cpp boost_1_52_0_patched/libs/filesystem/src/operations.cpp
--- boost_1_52_0/libs/filesystem/src/operations.cpp	2012-08-13 05:49:12.000000000 +0900
+++ boost_1_52_0_patched/libs/filesystem/src/operations.cpp	2012-11-21 13:27:58.861594656 +0900
@@ -73,13 +73,15 @@
     const fs::path dot_dot_path("..");
 #   include <sys/types.h>
 #   include <sys/stat.h>
-#   if !defined(__APPLE__) && !defined(__OpenBSD__)
+#   if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__) && !defined(ANDROID)
 #     include <sys/statvfs.h>
 #     define BOOST_STATVFS statvfs
 #     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
 #   else
 #     ifdef __OpenBSD__
 #     include <sys/param.h>
+#elif defined(__ANDROID__) || defined(ANDROID) // @Moss - Android messes up a bit with some headers, this one is the correct one :D
+#     include <sys/vfs.h>
 #     endif
 #     include <sys/mount.h>
 #     define BOOST_STATVFS statfs
@@ -206,7 +208,19 @@
          || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
 #   define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
 #   define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
+#if defined(__ANDROID__) || defined(ANDROID)
+    int BOOST_RESIZE_FILE(const char *path, off_t size)
+    {
+      int result = -1;
+      int fd = open(path, O_WRONLY);
+      if (fd != -1)
+	    result = ftruncate(fd, size);
+      close(fd);
+      return result;
+    }
+#else
 #   define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)
+#endif
 
 #   define BOOST_ERROR_NOT_SUPPORTED ENOSYS
 #   define BOOST_ERROR_ALREADY_EXISTS EEXIST
@@ -1906,7 +1920,11 @@
     if (max == 0)
     {
       errno = 0;
+#     ifdef __ANDROID__ || ANDROID
+      long tmp = 4096;
+#     else
       long tmp = ::pathconf("/", _PC_NAME_MAX);
+#     endif
       if (tmp < 0)
       {
         if (errno == 0)// indeterminate
diff -ur boost_1_52_0/tools/build/v2/user-config.jam boost_1_52_0_patched/tools/build/v2/user-config.jam
--- boost_1_52_0/tools/build/v2/user-config.jam	2011-01-25 10:06:12.000000000 +0900
+++ boost_1_52_0_patched/tools/build/v2/user-config.jam	2012-11-21 13:34:51.893594276 +0900
@@ -90,3 +90,54 @@
 
 # Configure specific Python version.
 # using python : 3.1 : /usr/bin/python3 : /usr/include/python3.1 : /usr/lib ;
+##################################################
+#
+#  android
+#
+##################################################
+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 ;
+
+}
+ANDROID_NDK_ROOT = c:/android/ndk-r8 ;
+modules.poke : NO_BZIP2 : 1 ; 
+
+using gcc : android4.6 :
+    $(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-g++ :
+    <archiver>$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ar
+    <ranlib>$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/$(androidPlatform)/bin/arm-linux-androideabi-ranlib
+    <compileflags>--sysroot=$(ANDROID_NDK_ROOT)/platforms/android-14/arch-arm
+    <compileflags>-I$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/include
+    <compileflags>-I$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include
+    <compileflags>-mthumb
+    <compileflags>-fno-strict-aliasing
+    <compileflags>-Os
+    <compileflags>-O2
+    <compileflags>-DANDROID
+    <compileflags>-D__ANDROID__
+    <compileflags>-DGLIBC
+    <compileflags>-D_GLIBCPP_USE_WCHAR_T
+    <compileflags>-D_LITTLE_ENDIAN
+    <compileflags>-DNDEBUG
+    <compileflags>-g
+    <compileflags>-lstdc++
+    <architecture>arm
+#    <cxxflags>-DBOOST_THREAD_VERSION=3
+    <cxxflags>-DPAGE_SIZE=2048
+    <cxxflags>-D__arm__
+    <cxxflags>-D_REENTRANT
+        ;
+