IS01にポータブルえせ開発環境を構築(その5) - Android NDKを使用して、rubyをビルド
さて、いよいよ、Android NDKを使用して、rubyをビルドする。いよいよ、Androidで動作するrubyが手に入るはずじゃ。しかし、残念ながら我がIS01では、制限により、このやり方では、rubyが動作しなかった。無念じゃ。/systemがreadonlyとなっているため、/system/libにrubyの共有ライブラリ(libruby.so)のシンボリックリンクが作成できない。そのため、ruby起動時に共有ライブラリのロードエラーが発生してしまう。
IS01をroot化して、/systemのreadonlyを無効にするか、別のarm系のrubyバイナリを持ってくるかすれば、うまく行く気がする。別途、挑戦してみたい。ここでは、とりあえず、NDK版rubyのビルド手順を書いておく。
環境変数の設定
NDKでビルドするために、環境変数をセットする。
$ export SYSROOT=$NDK_ROOT/build/platforms/android-4/arch-arm $ export CFLAGS="-march=armv5te -msoft-float " $ export CC="$NDK_ROOT/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -mandroid --sysroot=$SYSROOT"
これにより、クロスコンパイルすることができるようになる。
ruby1.9.2のソースコードを展開
rvmで、ruby1.9.2をインストールしているため、「~/.rvm/src/ruby-1.9.2-p0/」にソースコードが格納されている。ソースコードをビルドディレクトリにコピーする。(※ここでは、「/home/tmori/work/android/ndk/」をビルドディレクトリとする。)
$ cp -r ~/.rvm/src/ruby-1.9.2-p0/ /home/tmori/work/android/ndk/
configureの実行
ビルドディレクトリに移動し、armをターゲットとするmakeファイルを作成する。
$ cd /home/tmori/work/android/ndk/ruby-1.9.2-p0.android $ ./configure --host=arm-eabi --disable-ipv6 --prefix=/system/local --enable-shared
makeの実行
$ make
後は、makeを実行するだけなのだが、残念ながら失敗する。このページに書いてあるようにpatchを当てる必要がある。
また、configure.inを修正し、configreファイルを作成し直す必要がある。
patchの適用
rubyのソースコードとNDKのヘッダファイルにパッチを当てる。
$ cd /home/tmori/work/android/ndk/ $ patch -p0 < ruby.patch $ cd ~/work/android/android-ndk/build/platforms/android-4/arch-arm/usr/include $ patch -p0 < ndk.patch
ruby.patch
diff -u -r ruby-1.9.2-p0/configure ruby-1.9.2-p0.android/configure --- ruby-1.9.2-p0/configure 2010-08-18 14:56:27.000000000 +0900 +++ ruby-1.9.2-p0.android/configure 2010-08-19 11:36:01.000000000 +0900 @@ -13525,7 +13525,9 @@ $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : - as_fn_error "cannot check setpgrp when cross compiling" "$LINENO" 5 + #as_fn_error "cannot check setpgrp when cross compiling" "$LINENO" 5 + # hack for Android + ac_cv_func_setpgrp_void=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -15046,7 +15048,10 @@ LDFLAGS="$LDFLAGS -Zomf" ;; #( *) : - : ${LDSHARED='ld'} ;; +# : ${LDSHARED='ld'} ;; +# hack for Android + : ${LDSHARED='$(CC) -shared'} ;; + esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rb_cv_dlopen" >&5 $as_echo "$rb_cv_dlopen" >&6; } diff -u -r ruby-1.9.2-p0/dir.c ruby-1.9.2-p0.android/dir.c --- ruby-1.9.2-p0/dir.c 2010-08-09 13:39:57.000000000 +0900 +++ ruby-1.9.2-p0.android/dir.c 2010-08-19 13:17:16.000000000 +0900 @@ -700,8 +700,14 @@ static VALUE dir_set_pos(VALUE dir, VALUE pos) { +/* hack for Android*/ +#ifdef HAVE_SEEKDIR dir_seek(dir, pos); return pos; +#else + rb_notimplement(); +#endif + } /* diff -u -r ruby-1.9.2-p0/eval_intern.h ruby-1.9.2-p0.android/eval_intern.h --- ruby-1.9.2-p0/eval_intern.h 2010-06-03 18:58:32.000000000 +0900 +++ ruby-1.9.2-p0.android/eval_intern.h 2010-08-19 11:45:39.000000000 +0900 @@ -214,8 +214,12 @@ void rb_trap_restore_mask(void); #ifndef CharNext /* defined as CharNext[AW] on Windows. */ +#ifdef __ANDROID__ +#define CharNext(p) ((p) + 1) +#else #define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE)) #endif +#endif #if defined DOSISH || defined __CYGWIN__ static inline void diff -u -r ruby-1.9.2-p0/ext/nkf/nkf-utf8/nkf.h ruby-1.9.2-p0.android/ext/nkf/nkf-utf8/nkf.h --- ruby-1.9.2-p0/ext/nkf/nkf-utf8/nkf.h 2010-04-22 17:04:13.000000000 +0900 +++ ruby-1.9.2-p0.android/ext/nkf/nkf-utf8/nkf.h 2010-08-19 11:41:13.000000000 +0900 @@ -164,6 +164,10 @@ # ifndef HAVE_LOCALE_H # define HAVE_LOCALE_H # endif +#elif defined(__ANDROID__) +# ifndef HAVE_LOCALE_H +# define HAVE_LOCALE_H +# endif #else # ifndef HAVE_LANGINFO_H # define HAVE_LANGINFO_H diff -u -r ruby-1.9.2-p0/include/ruby/intern.h ruby-1.9.2-p0.android/include/ruby/intern.h --- ruby-1.9.2-p0/include/ruby/intern.h 2010-05-01 02:56:23.000000000 +0900 +++ ruby-1.9.2-p0.android/include/ruby/intern.h 2010-08-19 11:02:12.000000000 +0900 @@ -28,6 +28,9 @@ #endif #include "ruby/st.h" +#ifdef __ANDROID__ +#include <sys/select.h> +#endif /* * Functions and variables that are used by more than one source file of * the kernel.
ndk.patch
diff -u pthread.h.org pthread.h --- pthread.h.org 2010-08-16 17:00:54.000000000 +0900 +++ pthread.h 2010-08-16 17:01:25.000000000 +0900 @@ -87,6 +87,7 @@ */ #define PTHREAD_COND_INITIALIZER {0} +#define PAGE_SIZE 0x400 #define PTHREAD_STACK_MIN (2 * PAGE_SIZE) #define PTHREAD_CREATE_DETACHED 0x00000001 diff -u linux/in.h.org linux/in.h --- linux/in.h.org 2010-08-20 10:53:29.000000000 +0900 +++ linux/in.h 2010-08-20 10:53:45.000000000 +0900 @@ -29,7 +29,7 @@ IPPROTO_RSVP = 46, IPPROTO_GRE = 47, - IPPROTO_IPV6 = 41, + /*IPPROTO_IPV6 = 41,*/ IPPROTO_ESP = 50, IPPROTO_AH = 51,
configure.inの修正
/home/tmori/work/android/ndk/ruby-1.9.2-p0/configure.inをvi等で開き、AC_FUNC_SETPGRPと書いてある行をコメントアウトする。
#でコメントアウト #AC_FUNC_SETPGRP
$ autoconf
autoconfコマンドを実行し、configure.inからconfigureを作成する。
気を取り直して、makeを実行して、母艦の/data/localにインストールする。
$ make $ sudo mkdir -p /data/local/bin $ sudo make install
母艦の/data/local/binと/data/local/libをAndroidにコピーして、Androidの/system/libにリンクを作成する。
ln -s /data/local/lib/libruby.so /system/lib/libruby.so